深入解析Mifare Classic Crypto1流加密:从认证流程到密钥恢复实战
1. 项目概述为什么我们要深挖一张“过时”的卡片如果你接触过门禁卡、公交卡或者一些早期的电子钱包那么你大概率已经和Mifare Classic卡片打过交道了。这张诞生于上世纪90年代的卡片凭借其低廉的成本和在当时看来足够快的交易速度迅速占领了全球非接触式智能卡市场。然而它核心的Crypto1加密算法却成为了信息安全史上一个经典的“反面教材”。今天我们不是要简单地复现一个攻击而是要像外科手术一样完整地解剖其从认证到通信加密的整个流程。理解这个流程不仅是为了“破解”更是为了深刻理解对称流加密在资源受限的嵌入式环境中是如何实现的以及一个微小的设计缺陷如何导致整个安全体系的崩塌。这对于从事物联网安全、嵌入式开发甚至只是对底层安全机制好奇的开发者来说都是一次绝佳的学习机会。我们将绕过纯理论直接进入实战视角用你能看懂的语言和逻辑把每一步都掰开揉碎。2. 核心思路拆解逆向工程Crypto1的“心脏”要解析Crypto1不能把它当成一个黑盒。我们的思路是沿着卡片与读卡器交互的真实数据流一步步向前推进最终触及算法核心。2.1 从交互协议到加密边界Mifare Classic遵循ISO/IEC 14443 Type A标准进行无线通信。在未加密状态下读卡器和卡片通过明文进行“对话”。加密的触发点始于一个特定的命令认证Authentication。读卡器会选择一个扇区并向卡片发起认证请求。此时卡片和读卡器各自掌握着一个该扇区的密钥分为A密钥和B密钥。认证过程的核心目的就是让双方在不泄露密钥的前提下向对方证明“我知道密钥”。一旦认证成功后续的所有通信数据包括读、写、增值、减值等命令及其响应都将被一个动态生成的密钥流Keystream进行异或加密。所以整个流程可以清晰地划分为两个阶段认证阶段一个三次握手过程基于共享密钥和随机数挑战完成双向验证。加密通信阶段利用认证过程中产生的内部状态生成伪随机的密钥流比特对传输的每一个比特进行流加密。攻击者的经典思路如“幽灵”攻击和嵌套认证攻击正是利用了认证阶段随机数生成器的缺陷以及密钥流生成算法的线性特性通过监听一次或多次认证过程来逆向推导出密钥或直接预测后续密钥流。2.2 工具选型为什么是Proxmark3工欲善其事必先利其器。在Mifare Classic的研究中Proxmark3几乎是无可替代的“瑞士军刀”。它不仅仅是一个高频13.56MHz读卡器更是一个全功能的射频嗅探、模拟和攻击平台。硬件优势其开源的硬件设计允许我们直接捕获射频模拟信号并解码出原始的曼彻斯特编码或米勒编码数据这对于分析底层通信时序、捕捉认证过程中的完整数据帧至关重要。很多软件读卡器无法捕获到认证失败或异常的交互而Proxmark3可以。软件生态其强大的客户端pm3内置了丰富的Mifare Classic相关指令例如hf mf autopwn可以自动尝试多种攻击方式获取密钥hf mf nested用于执行嵌套认证攻击hf mf sim可以模拟卡片行为。更重要的是我们可以直接查看和操作其固件中实现的Crypto1算法相关函数进行单步调试和状态注入。不可替代性虽然也有像ChamelaonMini、Flipper Zero这样的便携设备但在功能的深度、灵活性和社区支持上Proxmark3依然是进行原理性研究和深度攻击验证的首选。注意使用Proxmark3进行安全研究必须在你自己拥有完全所有权的卡片或法律明确授权的测试环境中进行。对他人所属的卡片或系统进行未授权测试是违法行为。3. 实战解析第一阶段认证流程深度剖析现在让我们进入实战环节。假设我们手头有一张Mifare Classic 1K卡片和一个Proxmark3。我们首先来捕获并理解一次完整的认证过程。3.1 捕获一次明文认证会话在Proxmark3客户端我们首先将设备置于嗅探模式监听13.56MHz频段的通信。# 启动Proxmark3客户端 pm3 # 进入高频嗅探模式 hf 14a sniff然后我们用一个普通的读卡器或者Proxmark3的另一模式去读取卡片的某个扇区。Proxmark3会捕获到所有交互数据。一次成功的认证交互数据流通常如下所示数据为示例已简化读卡器 - 卡片:60 04// 认证请求命令60扇区号04对应第4扇区块地址计算方式为 扇区号*4卡片 - 读卡器:bb 63 dd 52 49 a1// 卡片返回一个4字节的随机数NT(例如bb 63 dd 52) 和其2字节的CRC-A校验值49 a1。读卡器 - 卡片:bb 63 dd 52 49 a1 88 69 b3 70// 读卡器发送NTNR(读卡器生成的4字节随机数例如88 69 b3 70) {NT}^{NR}^。这里的{NT}^和{NR}^是NT和NR经过某种变换后文详述后的结果。卡片 - 读卡器:NR^// 卡片返回读卡器随机数NR的变换值{NR}^。如果第4步验证通过认证成功。这里最关键的就是第3步中读卡器发送的{NT}^和{NR}^以及第4步卡片返回的{NR}^。它们就是“证明我知道密钥”的凭据。3.2 解密认证令牌{NT}^ 与 {NR}^ 的生成{NT}^和{NR}^并不是对NT和NR的直接加密而是Crypto1流密码算法在特定初始状态下产生的前32位密钥流与NT和NR进行异或XOR的结果。具体过程如下初始化密码机读卡器或卡片使用共享密钥Key和认证开始时收到的随机数NT对于读卡器是卡片发的对于卡片是自己生成的作为输入初始化Crypto1算法的48位移位寄存器LFSR。这个初始化过程是确定性的相同的Key和NT必然产生相同的初始状态。生成密钥流密码机初始化后开始运行。它会连续产生密钥流比特。丢弃前若干比特为了混淆后连续取出32个比特4字节这32个比特就构成了一个密钥流片段KS1。生成令牌将KS1与要发送的随机数对于读卡器是NT和NR对于卡片是NR进行按位异或得到的就是{NT}^和{NR}^。读卡器计算{NT}^ NT XOR KS1,{NR}^ NR XOR KS2(这里KS2是继KS1之后产生的下一个32位密钥流)。卡片验证卡片用同样的Key和NT初始化自己的密码机生成KS1用它去异或收到的{NT}^应该能得到自己发出的NT从而验证读卡器知道密钥。然后卡片再生成KS2用它异或收到的{NR}^得到NR接着用NR初始化实际上是参与下一步计算并生成KS3计算{NR}^ NR XOR KS3发回给读卡器。验证读卡器收到{NR}^后用自己计算出的KS3与之异或如果得到自己发出的NR则认证卡片成功。这个过程实现了双向认证且密钥Key从未在信道中传输。然而致命弱点在于随机数NT和NR的生成质量。早期Mifare Classic卡片的伪随机数生成器PRNG是线性的且状态可预测攻击者通过监听一次认证就能获得NT,{NT}^,NR,{NR}^四个值。由于{X}^ X XOR Keystream那么Keystream X XOR {X}^。攻击者可以直接计算出KS1和KS2来自读卡器以及KS3来自卡片响应的部分密钥流实操心得在嗅探时务必确保捕获到完整的四次数据交换。有时因为信号干扰数据包可能不完整。Proxmark3的hf 14a list命令可以查看缓存的完整数据帧比实时嗅探更稳定。对于关键测试建议多次捕获以确保数据一致性。4. 实战解析第二阶段Crypto1算法与密钥流生成拿到了几段密钥流片段我们如何攻击呢这就需要深入Crypto1算法的内部。4.1 Crypto1算法结构一个脆弱的LFSRCrypto1是一个基于48位线性反馈移位寄存器LFSR的流密码。它的核心是一个48位的寄存器每次时钟脉冲寄存器向右移动一位新的最高位由某些特定抽头位Tap经过一个非线性滤波函数f计算后填充。LFSR初始化密钥Key48位和随机数NT32位通过一个特定的混合算法并非简单拼接加载到LFSR中形成初始状态。这是整个算法安全的基础但混合过程也存在弱点。非线性滤波函数f为了增加复杂性算法从LFSR中选取20个位通过一个带有非线性的函数f计算出一个比特。这个比特再与下一个LFSR反馈位进行异或产生最终的密钥流比特。f函数的设计是保密的但已被逆向工程破解。密钥流生成每产生一个密钥流比特LFSR就移位一次。产生的密钥流比特与明文比特异或得到密文与密文比特异或得到明文。算法的安全性严重依赖于LFSR的初始状态即密钥的保密性。一旦初始状态被破解整个密钥流序列就可以被完全预测。4.2 从密钥流片段到密钥恢复已知明文攻击我们之前通过一次认证监听获得了至少96位的密钥流KS132位 KS232位 KS332位。由于Crypto1算法是线性的尽管有非线性滤波函数但其与LFSR状态的关系已被充分研究这些已知的密钥流比特构成了对48位LFSR初始状态即密钥的方程组。攻击的核心工具是相关性攻击或快速相关攻击的变种。由于滤波函数f的输入20个LFSR位和输出1个密钥流比特之间存在统计相关性攻击者可以建立大量的线性近似方程。已知的密钥流比特越多这些方程就越能精确地限定LFSR的初始状态。实际操作中我们不需要自己实现这些复杂的数学攻击。Proxmark3的hf mf nested命令自动化了这个过程它首先利用一个已知密钥的扇区例如扇区0通常使用默认密钥FFFFFFFFFFFF发起认证。在认证过程中它会尝试对目标扇区未知密钥发起“嵌套”认证。因为第一次认证已经建立加密通信所以嵌套认证的命令也是加密的。攻击工具会利用已知密钥产生的密钥流以及嗅探到的嵌套认证过程中的密文通过求解方程组来恢复目标扇区的密钥。这个过程通常只需要几秒钟到几分钟。# 假设我们已经知道扇区0的密钥是默认密钥 hf mf nested 0 A FFFFFFFFFFFF d # 尝试用已知密钥A去嵌套探测所有扇区的密钥注意事项嵌套攻击成功的前提是至少有一个扇区的密钥已知。这就是为什么Mifare Classic系统如果所有扇区都使用独立强密钥攻击难度会大大增加。但现实中很多系统为了管理方便多个扇区甚至所有扇区都使用相同或默认密钥这为攻击打开了大门。4.3 密钥流生成与通信加密模拟在成功恢复某个扇区的密钥后我们不仅可以解密该扇区的数据还可以完全模拟卡片或读卡器的加密通信。例如我们可以用Proxmark3模拟一张卡片并使用恢复的密钥来响应读卡器的认证请求# 将Proxmark3模拟成一张Mifare Classic卡片并加载指定扇区的密钥 hf mf sim u *1k # 模拟1K卡片UID为* hf mf eset 04 A A0A1A2A3A4A5 # 在模拟卡中设置第4扇区A密钥为A0A1A2A3A4A5当外部读卡器尝试认证第4扇区时Proxmark3会使用我们设定的密钥A0A1A2A3A4A5和它自己生成的NT或可指定的NT来计算正确的{NT}^和{NR}^完成认证流程。此后所有通信都将使用正确的密钥流进行加解密我们可以借此深入研究加密后的数据交换格式或者测试读卡器的行为。5. 常见问题与排查技巧实录在实际操作中你会遇到各种各样的问题。下面是我踩过的一些坑和解决方案。5.1 问题Proxmark3嗅探不到数据或数据混乱可能原因1天线问题或距离不当。Proxmark3的天线需要调谐且卡片与天线距离应在1-3厘米内。距离太远信号弱太近会导致过载失真。排查运行hw tune查看天线调谐情况。确保天线线圈完好没有断裂。尝试调整卡片与天线的相对位置和角度。可能原因2读卡器信号干扰。有些读卡器发射功率大或协议有微小差异可能导致Proxmark3无法正确解码。排查尝试使用Proxmark3自己作为读卡器hf mf rdbl等命令与卡片通信看是否能成功。这可以排除外部读卡器兼容性问题。可能原因3标签类型不匹配。Mifare Classic有1K和4K变种且ISO14443 Type A底层细节比特率、帧格式可能有差异。排查先用hf 14a reader或hf search命令识别卡片类型。在嗅探时明确指定标准hf 14a sniff -c或-r尝试不同的编码模式。5.2 问题嵌套攻击nested长时间无法成功可能原因1已知密钥错误或对应扇区不可用。嵌套攻击需要一个有效的已知密钥作为起点。如果提供的已知密钥错误或者该扇区被设置为永不接受认证例如某扇区的访问位被配置为拒绝任何认证尝试攻击无法开始。排查使用hf mf chk命令验证你提供的已知密钥是否真的能通过认证。使用hf mf fchk进行快速密钥扫描确认。检查目标扇区的访问条件Access Bits确认其是否允许认证。可能原因2捕获的认证数据不足或有误。嵌套攻击需要利用一次成功的认证过程数据。如果嗅探到的数据包不完整、时序错误或包含了校验错误攻击会失败。排查重新进行嗅探确保在已知密钥扇区认证时捕获到了清晰完整的NT,{NT}^,NR,{NR}^四组数据。可以使用hf 14a list仔细检查捕获到的数据帧。可能原因3目标密钥不是标准密钥或算法有变种。极少数情况下某些定制系统可能使用了非标准的密钥派生方法或修改了算法尽管Crypto1硬件是固定的。排查这比较棘手。可以尝试使用hf mf hardnested命令它是一种计算量更大但更鲁棒的攻击方式对某些特殊情况的容忍度更高。或者如果可能尝试获取系统的其他信息。5.3 问题模拟卡片sim时外部读卡器不响应或认证失败可能原因1UID不匹配。许多读卡器会检查卡片的UID唯一标识符如果模拟的UID不在其允许列表内会直接拒绝。排查尝试模拟一个原卡的UID如果你知道的话。或者对于只读UID的测试可以尝试使用一个常见的UID如0x08010203。使用hf 14a sim u UID进行模拟。可能原因2时序问题。Proxmark3的模拟模式在响应时间上可能与真卡有细微差异某些挑剔的读卡器可能会因此超时。排查这通常是固件或硬件限制。确保你使用的是最新版本的Proxmark3固件和客户端软件。尝试将Proxmark3和读卡器放得非常近减少信号延迟。可能原因3协议细节差异。除了ISO14443-3读卡器可能实现了某些厂商特定的指令或流程。排查使用嗅探模式捕获真卡与读卡器的完整交互流程然后与Proxmark3模拟时产生的交互进行对比查看在哪一步出现了分歧。可能需要编写自定义的Lua脚本来精确模拟特定流程。5.4 高级技巧利用“侦听-重放”进行无密钥操作在某些特定场景下甚至不需要恢复密钥。如果系统没有使用随机数或随机数质量极差例如每次认证NT都相同你可以直接侦听一次成功的加密通信数据包例如“扣款10元”指令然后将其原封不动地重放Replay。由于密钥流相同系统会再次执行相同操作。这就是重放攻击。操作使用Proxmark3的hf 14a snoop捕获完整交互保存为文件。然后使用hf 14a play将捕获到的信号原样发射出去。防护防御重放攻击的唯一有效方法是在交易中使用不可重复的随机数Nonce或递增序列号确保每次通信数据都不同。这也是现代安全协议的标准做法。通过对Mifare Classic Crypto1从认证到密钥流生成的完整拆解我们看到的不仅是一个算法的失败更是一系列安全设计原则的违背脆弱的伪随机数生成器、保密性通过隐匿算法最初保密、以及线性反馈移位寄存器在面临已知明文攻击时的固有脆弱性。今天Mifare Classic早已不再被视为安全设备但它的故事和其背后清晰可辨的技术脉络为我们理解现代加密技术如AES、认证协议如相互认证、随机数挑战以及安全单元SE的设计提供了极其宝贵的反面教材。在物联网设备泛滥的今天资源受限环境下的安全设计挑战依然存在避免重蹈Mifare Classic的覆辙是每一位嵌入式开发者和安全研究员应有的警觉。