本系列的上一篇文章讲了libnfc的安装与配置,这篇文章将着重分析Mifare Classic 1K卡的存储结构。

Mifare Classic 卡的存储结构

Mifare Classic 卡的容量分为三种,1K、2K和4K,我只用过容量为1K的,即S50卡,后面两种卡据说只是容量不同,存储格式一样。

Mifare卡的存储有扇区(Sector)和块(Block)两个概念,对于1K卡来说,其容量共1024字节,这1024个字节被分为16个扇区,每个扇区有4个块,每个块16字节,如下图所示:

mfs50storage.png

  • 厂商数据块

    Mifare卡的存储空间中,第0扇区的第0块为厂商数据块,该块是只读的,不过据说有一种Chinese Magic Card是可以修改该数据块的。

    该块中,0-3字节为UID,每张Mifare卡都拥有唯一的UID,所以很多小区的门禁系统使用UID作为门禁卡的标志来认证门禁卡,比如我们小区;第4字节据说是校验位,但我不清楚它是怎么进行校验的;第5字节为SAK,又称卡片容量,我不知道其他卡该字节的值是多少,我手上的Mifare卡该字节均为0x08;第6-7字节是ATQA应答字节,好像也经常被称为卡片类型,因为Mifare Classic 1K卡的ATQA均为0x0004(Mifare协议使用小端约定,低字节存放在低地址,高字节存放在高地址,即第6字节为0x04,第7字节为0x00);剩下的第8-15字节我也不知道是啥,我手里的多张卡读出来的值均为0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69

    第0扇区第0块的结构如下图所示:

    mfs50block0.png

  • 密钥块

    Mifare卡中每个扇区的最后一个Block为密钥块,又叫做尾块(Sector Trailer),该Block中存放了对应扇区的认证密钥以及权限设置,密钥块的结构如下图所示:

    mfs50trailerblock.png

    该块中,前6个字节与最后6个字节分别为密钥A和密钥B,当卡片出厂时,两个密钥均被设置为0xFF 0xFF 0xFF 0xFF 0xFF 0xFF,如果读密钥时,权限不足或认证失败则读出的值全为0。

    密钥块中,第6-9个字节为权限位,指明对应扇区相应的权限,其默认值为0xFF 0x07 0x80 0x69

  • 数据块

    除了密钥块和厂商数据块以外的Block为数据块,普通数据块可以作为可读写块或数值块,可读写块可以进行一般的读写操作,没什么特殊的,比较特殊的是数值块。

    • 数值块

      将普通数据块格式化为数值块后,可以把卡片当做电子钱包使用,其除了读写操作外,还可进行增值、减值、存储和传输操作,数值块的数据格式如下:

      mfs50valueblock.png

      根据官方文档的说法,为了保证数据的可靠性,在一个数值块中,数值存储三次,一次取反,两次不取反;地址存储四次,两次取反,两次不取反。

      例如:将Sector 0 Block 2设置为数值块,其值设置为十进制200,则block 2中的数据为:00 00 00 C8 FF FF FF 37 00 00 00 C8 02 FD 02 FD

权限控制

前面说到S50卡中,通过扇区尾块的权限位(Access Bits)来控制一个扇区相应的权限,权限位为尾块中的第6-9个字节。每个扇区中对应的Block的权限由三个位控制,表示为 C1n C2n C3n。例如Block 0的权限位表示为:C10 C20 C30

mfs50accessconditions.png

权限位在尾块中的存储结构如下图所示:

mfs50accessbitsstruct.png

如果需要修改扇区中某个块的访问权限,需要根据控制条件修改权限位并存储到对应扇区尾块的Access Bits区中,数据块的控制条件如下图所示:

mfs50dbaccess.png

上图中Access Bits列表示权限位的组合,Access conditions for列表示进行对应操作时需要认证的密钥,never表示不可进行对应操作。Application列表示应用在何种类型的操作或数据块上。

需要注意的是,尾块的权限控制与数据块不同,尾块的控制条件如图:

mfs50tbaccess.png

如果不需要使用key B,可在尾块中将key B的存储空间当做数据块使用,但需要配置相应的权限。

卡片认证流程

当对S50卡的一个Block进行操作时,需要根据其权限的设置来选择对应的密钥进行认证,其认证流程如下:

  1. 选卡

    当S50卡进入PN532的可通信范围后,需要控制PN532选择卡片进行通信,如果有多张卡同时进入可通信范围,需要抗干扰算法选择其中一张进行通信。

  2. 认证

    当PN532与S50卡之间建立通信连接后,需要根据权限位选择对应的密钥对扇区进行认证,如果认证失败,则需要断开连接重新选卡才能再次认证。

  3. 操作

    认证成功后可以对已经认证的扇区进行操作,操作完成后断开连接即可进行下一次选卡。

总结

从上一篇到现在拖了将近两个月,目睹了大佬们的博客之后还是把这篇写出来了……下一篇将着重总结一下libnfc控制PN532的具体代码,先列标题:在树莓派上使用 PN532 NFC读卡器[2]——libnfc 控制PN532