You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读取Mifare Classic 1k标签认证阶段的挑战随机数?

可以通过底层通信获取Mifare Classic 1K的认证Challenge Nonce

完全可以绕过javax.smartcardio的抽象封装,直接通过ACR122U发送底层APDU指令,仅执行Mifare Classic认证流程的第一步,获取标签返回的challenge nonce。具体实现方式如下:

核心原理

Mifare Classic的认证流程第一步是:读卡器向标签发送认证指令(指定密钥类型A/B和目标扇区的认证块),标签会直接返回4字节的challenge nonce,这一步不需要提前提供密钥(后续的密钥验证是流程的第二步)。ACR122U支持通过特定格式的APDU封装Mifare原生指令,直接与标签交互。

具体步骤

1. 构造认证请求APDU

ACR122U要求用如下格式的APDU封装Mifare原生指令:

FF 00 00 00 [LEN] [MIFARE_CMD] [PARAMS]

针对认证第一步,构造的APDU为:

  • 认证A密钥:FF 00 00 00 02 60 [BLOCK_ADDR]
  • 认证B密钥:FF 00 00 00 02 61 [BLOCK_ADDR]

其中[BLOCK_ADDR]是目标扇区的认证块地址:Mifare Classic 1K共16个扇区,每个扇区包含4个块,扇区n的认证块地址为3 + 4*n(例如扇区0的认证块是块3,对应地址0x03)。

2. 发送APDU并捕获Challenge Nonce

使用支持直接发送原始APDU的库(如Python的pyscard,比javax.smartcardio更灵活)发送上述指令,标签返回的4字节数据即为challenge nonce。

Python示例代码(基于pyscard)

from smartcard.System import readers
from smartcard.util import toHexString, toBytes

# 初始化读卡器连接
reader = readers()[0]
conn = reader.createConnection()
conn.connect()

# 构造扇区0(认证块3)的A密钥认证请求APDU
auth_apdu = [0xFF, 0x00, 0x00, 0x00, 0x02, 0x60, 0x03]
response_data, sw1, sw2 = conn.transmit(auth_apdu)

# 处理响应
if sw1 == 0x90 and sw2 == 0x00:
    # response_data即为4字节的challenge nonce
    print(f"获取到Challenge Nonce: {toHexString(response_data)}")
else:
    print(f"请求失败,状态码: 0x{sw1:02X}{sw2:02X}")

注意事项

  • 部分旧公交卡可能对认证指令有限制,如果返回非0x9000的状态码,可尝试更换扇区的认证块地址。
  • 若读卡器模式异常,可先发送FF 00 00 00 01 01切换到Mifare兼容模式。
  • 即使不知道标签的密钥,只要标签支持Mifare Classic协议,发送认证指令后就会返回challenge nonce,这正是验证LFSR漏洞所需的前提。

内容的提问来源于stack exchange,提问作者f3ssen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 03:55:26