一个实验教你怎么"锁住数据",一个实验教你怎么"验明正身"。两张卡片的距离,就是安全体系从"你有什么"走到"你是谁"的距离。
引子:这轮两个实验,主题都是"安全"
- B04 RFID 读写加密实验:RC522 读卡器 + DES 加密,给卡里的数据上锁;
- B05 生物识别实验:AS608 指纹模块,让"你的指纹"变成钥匙。
一个是数据安全(卡里的内容不许别人看),一个是身份安全(只有你能通过验证)。它们回答的是同一个问题的两个面:"凭什么相信这张卡/这个人?"
而且这两个实验的技术跨度也很大:B04 还是经典的裸机大循环 + 按键状态机,B05 已经切换成 LiteOS 多任务 + WiFi 上云。顺着这个顺序读代码,正好把"单机应用 → 系统应用"的差距看得很清楚。
一、B04:RFID 读写加密——给卡片数据上把 DES 锁
1. 先看主框架:裸机 + 按键模式状态机
main 的结构非常"教科书":初始化 → 每秒轮询一次 RC522 → 按键实时检测。
while (1)
{
Key_Task(); // 按键检测(决定工作模式)
if ((HAL_GetTick() - tickstart) >= 1000)
{
tickstart = HAL_GetTick();
RC522_Handle(); // RFID 综合处理
led_toggle(LED1_Pin);
}
}
核心设计是 RCC522_Work_Mode 工作模式状态机:
按键 模式 功能
KEY1 1 数据加密(明文 → DES 密文 → 写入卡片)
KEY2 2 数据解密(读密文 → DES 解密 → 显示明文)
KEY4 0 卡片初始化(新卡先初始化才能用)
屏幕和串口都会提示"请先按键设置功能再刷卡"——先选模式、再刷卡,这是整个实验的使用流程。
2. 读卡四步曲:寻卡 → 防冲撞 → 选卡 → 认证
RC522 读卡不是"往那一放就读",而是分步走的协议流程:
status = RC522_Search_Cards(PICC_REQALL, card_type); // ① 寻卡:感应区内有没有卡
if (status == MI_OK)
{
status = RC522_Anticoll(card_id); // ② 防冲撞:多卡同时出现时选一张,拿到卡号
}
if (status == MI_OK)
{
// ③ 选定卡 → ④ 密钥认证 → 读/写数据块
}
这是理解射频识别(RFID)的关键:射频信道是共享的,多张卡同时在场会"冲撞",必须靠防冲撞算法逐张选出来——和人多说话会吵一样,通信协议要先解决"谁先说"。
3. 卡内结构:16 个扇区,每扇区 4 块
代码注释把 M1 卡的存储结构写得明明白白:
- 卡分 16 个扇区,每扇区 4 块(块 0/1/2 是数据块,块 3 是控制块/密钥块),共 64 块按绝对地址 0~63 编号;
- 第 0 扇区的块 0 存放厂商代码,出厂固化,不可更改;
- 本实验默认使用 Sector ID = 1,Block ID = 0、1:块 0 存数据,块 1 存加密标志;
- 初始密钥 Pass_Word = {0xFF x 6}(出厂默认)。
经典警告(代码原话):切忌往每个扇区的块 3 写数据——它是密码区,有指定数据格式,乱写会导致扇区无法访问、直接废掉。这是 RFID 实验的"高压线"。
4. DES 加密:数据的"锁"与"钥匙"
加密用 DES 对称加密算法(des.c/des.h),密钥是 8 字节:
uint8_t Key_des = {0x12,0x34,0x56,0x78,0x12,0x34,0x56,0x78}; // DES 8 字节密钥
uint8_t Block_Date = {"123456"}; // RFID 卡原始(明文)数据
加密流程(KEY1 按下 + 刷卡):
RC522_Read_Date(块0地址, card_date); // 读卡片原有数据
memcpy(&blockdata, &card_date, 16); // 拷到缓存
if (块1 数据 == 0x5A && 块1 数据 == 0xA5) // 检查是否已加密
{
printf("RFID卡数据已加密,无需再次加密\r\n"); // 已加密则拒绝重复操作
return;
}
Process_Message(&blockdata, &des_encryptiondata, Key_Sets, ENCRYPTION_MODE); // DES 加密
/* 加密数据写入块 0,0x5A 0xA5 标志写入块 1 */
解密流程(KEY2 按下 + 刷卡)则反过来:读密文 → DECRYPTION_MODE 解密 → 明文显示,同时清掉加密标志。加密、解密、初始化三个模式共用同一个 RC522_Handle(),靠 RCC522_Work_Mode 分流,成功时蜂鸣器提示(BEEP_RING())。
这个实验的价值:RFID 卡本身没有"密码保护你的数据"的能力,只有扇区密钥认证。真正让"123456"这串数据在卡里不可读的,是应用层加的 DES 加密——把明文换成密文再存卡,读卡器拿到手也是一堆乱码。这就是"数据在存储环节加密"的完整落地。
二、B05:生物识别——你的指纹就是钥匙
B05 的工程一打开就是熟悉又陌生的味道:LiteOS、LOS_KernelInit、esp8285.h、ocprotocol.h——和上一轮的电子围栏是同一套平台骨架,只是业务从"围栏"换成了"指纹"。
1. 三个任务,各管一摊
HAL_Init();
sysclkinit();
task_view_init(); // 显示任务初始化
task_control_init(); // 控制任务初始化
task_finger_init(); // 指纹任务初始化(AS608 读状态引脚)
LOS_KernelInit();
creat_control_task(); // 控制任务
creat_view_task(); // 显示任务
creat_finger_task(); // 指纹任务
LOS_Start();
- finger_task:指纹模块的采集与业务(录/删/查/比对);
- control_task:按键、网络状态等控制逻辑;
- view_task:LCD 分页显示(状态页 / 调试页),屏显"指纹传感器实验"。
2. finger_task 的可靠性设计
指纹任务循环里有两个细节值得单独拿出来讲:
① 首启清库:任务第一次运行时先 Del_FR() 清空指纹库,保证从干净状态开始,避免上一次实验残留的指纹干扰判断。
if (first_flag)
{
first_flag = 0;
Del_FR(); // 首次启动清空指纹库
LOS_TaskDelay(100);
}
② 模块握手重连:AS608 是独立指纹模块(UART 串口通信),掉线是常态,所以每次操作前先握手,失败就重试、最多 5 次:
while (PS_HandShake(&AS608Addr))
{
DEBUG_PRINT(MODULE_AS608, "Cannot connect with AS608!");
LOS_TaskDelay(200);
i++;
if (i > 5) { i = 0; break; } // 重试 5 次放弃
}
设备外设不是"插上就永远在线"的——这是从裸机思维走向系统思维的重要一课:真实系统要把"设备不在线"当作正常情况来处理。
3. 四大功能:录、删、查、比对
按键 + 按压,对应指纹的完整生命周期:
操作 函数 说明
KEY1 Add_FR() 录指纹(按提示按压两次采集特征入库)
KEY2 Del_FR() 删指纹
KEY4 PS_ValidTempleteNum(&ValidN) 查指纹库剩余容量(AS608Para.PS_max - ValidN)
直接按压 Finger_press() 实时比对:按一下,模内比对,返回匹配结果
每一步都有蜂鸣器反馈(Beep_Ringing():beep 400ms),按压成功/失败通过不同提示音区分——好的交互设计在嵌入式里也一样重要。
4. 上云:识别结果不止留在本地
工程里挂着 esp8285.h(WiFi 模组)和 ocprotocol.h(OC 云协议),指纹/控制任务的结果可以通过 WiFi 上报平台,配合 view_task 的"模块状态/调试信息"分页,这已经是一个可以远程查看状态的指纹门禁系统雏形了。
三、主线:两种"钥匙",同一套安全逻辑
把两个实验并排看,会发现它们惊人地互补:
维度 B04 RFID 读写加密 B05 生物识别
认证依据 你持有的卡(something you have) 你本身的指纹(something you are)
核心模块 RC522(13.56MHz,SPI) AS608(UART 串口)
数据保护 DES 对称加密(明文→密文落卡) 指纹特征模板(不可逆存储)
编程模型 裸机大循环 + 按键状态机 LiteOS 多任务
交互 LCD + 串口 + 蜂鸣器 LCD 分页 + 蜂鸣器 + WiFi 上云
防呆设计 已加密标志 0x5A/0xA5 防重复加密 首启清库 + 握手重连防失效
看懂这张表,就看懂了这个领域:
- 卡认证解决"认物":卡可以复制、可以借、可以丢,所以必须在数据层加 DES 加密——锁住的是"内容";
- 生物认证解决"认人":指纹复制不了、丢不了,锁住的是"身份";
- 两者的工程骨架是同一套:先握手上电 → 检测/录入 → 本地验证 → 反馈(蜂鸣器/LCD)→(可选)上报云平台。
而且 B05 的 LiteOS 三任务结构和上一轮电子围栏几乎同构——说明这套平台已经把"传感器/模块接入 + 多任务 + 上云"做成了可复用的工程模板,换一个业务模块,就是换一个任务而已。这对"从实验到产品"的理解特别有价值。
四、踩坑记录(给后来人)
1. 别碰块 3(密钥块):M1 卡的 3/7/11/.../63 号块是密码区,格式特殊,乱写会永久废掉扇区。写数据前先背下"数据块 0/1/2、控制块 3"的划分。
2. 新卡先初始化:出厂卡可能没有有效的扇区密钥结构,直接加密会失败。main 里专门提示"如果是新卡,请先进行初始化操作"——KEY4 初始化是第一步,不是可选项。
3. 防冲撞不是可省的步骤:多张卡同时放在感应区时,没有 RC522_Anticoll 拿不到唯一卡号。做多卡场景时这个步骤的位置不能动。
4. 加密要有"已加密"标志:B04 用块 1 的 0x5A 0xA5 标记卡是否已加密,重复加密会被拒绝。任何"只做一次"的写入操作,都要有幂等保护,否则重按一次按键数据就毁了。
5. 指纹模块会掉线,要握手重连:AS608 每次操作前 PS_HandShake,失败重试 5 次。裸机思维是"假设设备永远在线",系统思维是"设备掉线是常态,必须有重连策略"。
6. 首启要清库:指纹模块的 Flash 里存的是上一次实验的指纹。B05 用 first_flag 在任务启动时清一次库——初始化状态要显式建立,不能赌"出厂是干净的"。
7. RTOS 里别用 HAL_Delay 死等:finger_task 里所有等待都是 LOS_TaskDelay(),让出 CPU 给其他任务。这和上一轮围栏实验的教训一致,是裸机 → RTOS 最常见的迁移错误。
五、写在最后
两个实验做下来,最大的感悟是:"安全"在嵌入式里从来不是一个算法,而是一个闭环。
B04 告诉我们闭环是——密钥 + 加密 + 存储 + 标志位:光有 DES 算法不够,还要决定把密文放哪个块、用什么标志防止重复加密、新卡怎么初始化,缺一环都不成立。
B05 告诉我们闭环是——采集 + 存储 + 比对 + 反馈 + 上云:指纹模块只是"眼睛",真正让它成为门禁的是任务调度、重连机制、蜂鸣器反馈和云平台上报这一整套工程。
如果把这几轮实验连起来看,主线就更清楚了:从读传感器(数据从哪来),到加密存储(数据怎么保护),再到生物识别(身份怎么验证)——一块板子,正在一步步逼近真实的物联网产品。
下一步的方向也很自然:
- 把 B04 的加密卡和 B05 的指纹组合成"刷卡 + 指纹"双重认证(门禁系统标准做法);
- 指纹比对结果通过 OC 协议上报云端,做远程开门、访客记录;
- 把 B04 的 DES 密钥从固定写死升级为密钥动态下发,进一步贴近真实安全设计。
到那时,"刷卡刷指纹"就真的变成一个可以落地的产品了。