Mifare1 Card破解

前言

从M1卡的验证漏洞被发现到现今,破解设备层出不穷,所以快速傻瓜式一键破解不是本文的重点,年轻司机将从本文中获得如下技能。

  • 如果你想简单快速的上手,你可以选择ACR122-like,Proxmark3等容易购买到的操作简单的设备,或者有个带有NFC功能并安装有安卓Mifare ClassicTool (MCT)软件的手机也是个不错的选择。
  • 本文基于树莓派加RC522,PN532模块试验,如果你是刚入门的Geek爱好者不妨读读本文,我将简明地叙述SPI接口协议和部分RC522驱动代码。
  • 本文破解皆指针对Mifare Classic卡获得KeyA,KeyB,实现扇区数据读取。
  • 本文旨在抛砖引玉,才疏学浅,如有错误还请不吝赐教。

M1卡结构

Mifare是NXP公司生产的一系列遵守ISO14443A标准的射频卡,包括Mifare S50、Mifare S70、Mifare UltraLight、Mifare Pro、Mifare Desfire等。Mifare S50的容量为1K字节,常被称为Mifare Standard,又被叫做Mifare 1,是遵守ISO14443A标准的卡片中应用最为广泛、影响力最大的的一员。S50的卡类型(ATQA)是0004H。

1

在带有NFC功能的手机上使用MCT读取空白卡Mifare Classic 1k(S50),我们可以直观地看到卡片的存储结构。

32

M1卡有从0到15共16个扇区(Sectors),并且每个扇区都有独立的密码,每个扇区配备了从0到3共4个块(Block),16个扇区的64个块按绝对地址编号为0~63,每个块可以保存16字节byte的内容,共有16X4X16=1024byte。

每个扇区的第4段用来保存KeyA,KeyB和控制位(ACs控制读写权限)。

0扇区0块是特殊的数据块,用于存放制造商代码,包括芯片序列号,此块只读。

4

SPI接口

SPI串行外设接口(Serial Peripheral Interface)是一种高速的,全双工,同步的通信总线,SPI通信以主(master)从(slave)方式,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是SDI(数据输入MISO)、SDO(数据输出MOSI)、SCLK(时钟SCK)、CS(SS片选)。

CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效。

通讯是通过两个双向移位寄存器进行数据交换。SPI是串行通讯协议,数据是一位一位传输的(总是先发送或接收高字节MSB数据)。SCLK提供时钟脉冲,在通过 SDO线输出时,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取,完成一位bit数据传输。因此,至少需要8次时钟信号的改变才能完成8位数据1byte的传输。

5

6

SPI协议是一种如何传输数据的方式,在集成了SPI硬件控制器的树莓派中我们不需要会复杂的软件模拟SPI,我们只要会使用相关库bcm2835发送和接收数据就行了。就像是流水线上的履带运输机,我们要做的只是把货物放在上面(而不是还要想办法怎么搭建运输机),当然我们还得知道怎么放,下面我们学习RC522模块的控制。

MFRC522

几个重要特性

  • 支持ISO 14443A/MIFARE
  • 64字节的发送和接收FIFO缓冲区
  • 3V电源电压
  • 支持SPI,I2C,UART接口

如何与M1卡通信?

  • Request standard/all。在上电复位Power-On Reset(POR)后,M1卡发送ATQA码(卡片类型码,如00 04h 代表MF1S503yX)回应REQA请求或者唤醒WUPA命令。
  • 防冲突机制。如果读卡器感应区存在多张卡,他们需要以自己的标识符(发送4字节的SN和1字节校验)来区分并且只有被选中的一张卡才能进行下一步操作。
  • 选卡。读卡器使用选卡命令选择一张卡作为验证和存储相关操作,卡片返回选择应答SAK码(卡片容量)。
  • 3次互相验证。在选卡之后,读卡器指定存储地址,使用相应的密码完成3次互相验证步骤。验证通过之后所有的存储操作都是加密的。
  • 存储器操作。

读(Read):读数据块

写(Write):写数据块

减值(Decrement):减少数据块内的数值,并将结果保存在临时内部数据寄存器中

加值(Increment):增加数据块内的数值,并将结果保存在数据寄存器中

转存(Restore):将临时内部数据寄存器的内容写入数值块

暂停(Halt ):将卡置于暂停上作状态

7

几个重要的寄存器

FIF0DataReg,FIFO缓冲区的输入和输出数据总线连接到FIFODataReg寄存器,通过写FIFODataReg寄存器来讲一个字节的数据存入FIFO缓冲区,之后内部FIFO缓冲区写指针加1。

主要的状态指示寄存器包括ComIrqReg、Er-rorReg、Status2Reg和FIFOLevelReg等。

(更多详细内容请查看芯片手册,这也是必须的)

8
(通信流程)

读写操作

写卡分两步骤

Step A:查询块状态。

命令码(0xA0) 块地址

若块准备好,则MIFARE卡返回4比特应答。若值为1010,则可进行下一步操作;若值非1010,则表示块未准备好,必须等待直至块准备好为止。

Step B:写数据。

数据字节(16字节) CRC(2字节)

若写入成功,则MIFARE卡返回4比特应答,值仍为1010;若非lOl0,则表示写入失败。

读卡

指令格式

命令码(0x30) 块地址

若执行成功,则MIFARE卡返回18字节应答比特。需要注意的是,其中只有16字节是读取的块数据,另外2个字节为填充字节。若字节数不为18,则可判断读卡操作错误。

* 函 数 名:write

 * 功能描述:写块数据

 * 输入参数:blockAddr--块地址;writeData--向块写16字节数据

unsigned char write(unsigned char blockAddr, unsigned char *writeData)

{

  unsigned char status;

  unsigned int recvBits;

  unsigned char i;

  unsigned char buff[18];

 

  buff[0] = PICC_WRITE;

  buff[1] = blockAddr;//块地址0-63

  calculateCRC(buff, 2, &buff[2]);

//发送指令

  status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);

 

//这里判断返回状态

  if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))

    status = MI_ERR;

  //准备16byte数据

  if (status == MI_OK){

    for (i=0; i<16; i++)    //?FIFO?16Byte?? Datos a la FIFO 16Byte escribir

      buff[i] = *(writeData+i);

    //计算校验位

calculateCRC(buff, 16, &buff[16]);

//发送数据

    status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);

    if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))

      status = MI_ERR;

  }

  return status;

}