☰
MIFARE Classic Tool 完全指南:Android 上读取、写入与分析 MIFARE Classic RFID 标签
2026/10/10 2:43:45 网站建设 项目流程
  • 移动开发

【免费下载链接】MifareClassicTool

An Android NFC app for reading, writing, analyzing, etc. MIFARE Classic RFID tags.

项目地址:https://gitcode.com/gh_mirrors/mi/MifareClassicTool
点击查看免费下载

MIFARE Classic Tool(MCT)是一款面向 Android 平台的 NFC 应用,专门用于对 MIFARE Classic RFID 标签执行读取、写入、克隆与分析等底层操作。本文以仓库根目录的 README.zh-CN.md 为主体骨架,并结合仓库内 MCReader.java、MainMenu.java 等源码实现,深入讲解 MCT 的功能清单、使用前提、密钥文件(字典)体系与"字典攻击"式读取原理。读完本文,你将掌握如何准备密钥、构造密钥文件、用 MCT 最大限度读取标签,以及理解底层十六进制数据操作背后的技术机制。

项目定位:面向熟悉 MIFARE Classic 的底层工具

MCT 提供的功能非常底层,它的目标用户是至少基本熟悉 MIFARE Classic 技术的开发者与安全研究者。所有数据输入和输出均为十六进制(hex),因此用户还需要理解十六进制数系统。

需要特别说明的是,MCT不会通过图形界面帮你"把 URL 保存到 RFID 标签"这类上层封装操作——如果你想在标签上保存任何内容,必须自行输入原始十六进制数据。这正是它作为底层研究工具的核心定位。

应用本身是免费软件(开源),采用 GPLv3 许可,最初由 Gerhard Klostermeier 与 SySS GmbH 及亚伦大学(www.htw-aalen.de)在 2012/2013 年合作开发(见 README.zh-CN.md)。

特性总览:MCT 能做什么

MCT 的能力可以按"读、写、分析、辅助"四类归纳,仓库中的 Activity 与工具菜单(tools.xml)一一对应:

读取与数据管理

  • 读取 MIFARE Classic 标签;
  • 保存、编辑和分享读取到的标签数据(转储 Dump);
  • 以高亮的十六进制形式查看标签数据(DumpEditor.java);
  • 以 7-Bit US-ASCII 形式查看标签数据;
  • 显示标签的一般信息(TagInfoTool.java)。

写入与克隆

  • 写入 MIFARE Classic 标签(逐块写入,见 WriteTag.java);
  • 克隆 MIFARE Classic 标签:将某标签的转储按文件(dump-wise)写入另一个标签;
  • 快速 UID 克隆功能(CloneUidTool.java);
  • 将标签格式化为出厂/交付状态;
  • 对特殊类型的 MIFARE Classic 标签写入制造商块(块 0);
  • 使用外部 NFC 读取器(如 ACR 122U)。

分析工具(工具菜单,共 9 项)

  • 解码/编码 MIFARE Classic 值块(Value Block,ValueBlockTool.java);
  • 解码/编码 MIFARE Classic 访问控制条件(Access Conditions,AccessConditionTool.java);
  • 比较转储(Diff Tool,DiffTool.java);
  • 以整数形式查看标签数据(ValueBlocksToInt.java);
  • 计算 BCC(Block Check Character,信息组校验码,BccTool.java);
  • 导入/导出/转换文件(ImportExportTool.java);
  • 内建离线的帮助与信息(help.html)。

从 MainMenu.java 的onContextItemSelected()可以看到,上述分析工具由主界面"工具"按钮的上下文菜单统一分发;而主界面其余按钮则分别进入读标签(ReadTag)、写标签(WriteTag)、密钥编辑器(KeyEditor)与转储编辑器(DumpEditor)。

使用前必须知道的重要信息

原 README 用专门一节强调了若干使用前提,这些直接影响实际操作结果:

  1. MCT 无法"破解"任何 MIFARE Classic 密钥。要读/写某个标签,你首先必须拥有该标签的密钥(见下文"入门"一节)。
  2. 不会提供暴力破解功能——因为 MIFARE Classic 协议认证速度太慢,暴力枚举在手机上不现实。
  3. 卸载应用会永久删除其保存的所有文件(转储/密钥)。MCT 将数据以文件形式保存在应用私有目录中,卸载即清空,务必提前用"导入/导出工具"备份。
  4. 块 0 只读限制:原始 MIFARE Classic 标签的第一个扇区第一个块(制造商块,块 0)是只读的,无法写入任何数据。
  5. 硬件兼容性:部分手机的 NFC 控制器不支持 MIFARE Classic,MCT 在这些设备上无法使用。仓库维护了 INCOMPATIBLE_DEVICES.md(已知不兼容设备列表)与 COMPATIBLE_DEVICES.md,购买/选机前建议查阅。

关于"魔术标签"与块 0 写入的细节

原文档对特殊标签的说明非常详尽,这里完整保留并补充技术背景:

  • 2 代魔术标签(Gen2,即中文购物网站常见的 CUID 卡):支持通过简单写命令写入制造商块。MCT 能够写入此类标签,因此可以创建完全正确的克隆。
    • 某些 CUID 卡无法使用,详见 RfidResearchGroup/proxmark3 的 magic_cards_notes 文档;但中文购物网站上通常不必担心遇到这类特殊卡片。
    • FUID/UFUID 理论上也可用,但尚未经过测试,欢迎在 issue 中反馈实际效果。
  • 1 代魔术标签(Gen1,即中文购物网站常见的 UID 卡):需要特殊命令序列才能进入可写制造商块状态。由于 Android NFC API 的限制,MCT 无法发送这类特殊命令序列,因此无法写入此类标签的制造商块。购买时请注意区分!
  • 写入块 0 的校验要求:请确保 BCC 值(可用"BCC 计算器"工具计算)、SAK 和 ATQA 值都正确。如果只是想克隆 UID,请使用"克隆 UID 工具"(CloneUidTool)。

值得补充的是,MCReader.java 中还保留了一个writeBlock0Gen3()方法(针对 Gen3 卡的 APDU 写入方案),但源码注释明确指出该方案在测试中会导致 4K 标签的 0-31 扇区损坏,因此当前并未启用——这体现了项目在块 0 写入功能上的谨慎取舍。

启动时的硬件检查链

从 MainMenu.java 的runStartUpNode()可以看到,MCT 启动时会依次检查:是否首次使用 → 是否有 NFC 硬件 → 硬件是否支持 MIFARE Classic → NFC 是否开启 → 是否需要外部 NFC 服务 → 是否显示捐赠弹窗 → 处理新标签 Intent。

对于不支持 MIFARE Classic 的设备,应用会提示安装外部 NFC 服务(eu.dedb.nfc.service),或允许以"仅编辑器模式"(Editor Only)继续使用转储/密钥编辑功能(useAsEditorOnly())。这解释了 README 中"使用外部 NFC 读取器(如 ACR 122U)"特性的落地方式:通过 Android 的 NFC 转发机制配合外部读卡器服务完成标签交互。

入门:密钥获取与字典攻击式读取

这是原文档的实战核心章节,也是 MCT 最具特色的设计。

第一步:获取标签密钥

MIFARE Classic 存在已知的密码学缺陷(Crypto1 流密码),因此可以使用Proxmark3、普通 RFID 读卡器配合专用工具(如mfcuk、mfoc)找回标签的全部密钥(包括密钥 A 与密钥 B)。这是读取任何标签的前提。

第二步:使用内置标准密钥文件

应用自带标准密钥文件,位于assets/key-files/目录下:

文件说明仓库路径
std.keys最常见标准密钥(3 个)std.keys
extended-std.keys扩展标准密钥集,收集自公开渠道(数百个)extended-std.keys
hotel-std.keys已知可工作于部分酒店门锁的密钥hotel-std.keys

std.keys的内容非常简单,仅包含 3 个广为流传的密钥:

# Standard keys FFFFFFFFFFFF A0A1A2A3A4A5 D3F7D3F7D3F7

其中FFFFFFFFFFFF是 MIFARE Classic 的出厂默认密钥(在 MCReader.java 中以DEFAULT_KEY常量定义)。extended-std.keys则汇集了来自 mfoc、mfterm、RfidResearchGroup/proxmark3 默认字典以及多篇公开 pastebin 的密钥,还包含莫斯科 Troika 交通卡、莫斯科社保卡等特定场景密钥,是快速试探标签的最佳起点。

这些密钥文件由 MainMenu.java 的copyStdKeysFiles()在首次启动时从 assets 复制到应用私有目录(HOME_DIR下的key-files/目录,见 Common.java)。注意:对内置标准密钥文件的修改会在应用更新/重装时丢失,自定义密钥请创建自己的密钥文件。

你可以直接在主界面点"读标签"(ReadTag),用这些标准密钥文件尝试读取标签。

第三步:创建与导入自己的密钥文件

一旦你获知部分密钥,就可以把它们放入一个简单的文本文件中(每行一个密钥):

FFFFFFFFFFFF A0A1A2A3A4A5 你的其他密钥

创建方式有两种:

  • 在 PC 上编辑好文本文件,然后用 MCT 的**"导入/导出工具"**(ImportExportTool)导入;
  • 或在应用内通过主界面的**"编辑/新建密钥文件"**(KeyEditor)直接创建。

密钥文件的具体格式约束可以从源码中得到精确印证:MCReader.java 的setKeyFile()逐行解析密钥文件时要求:

  • 每行密钥必须是12 个十六进制字符(6 字节,正则[0-9A-Fa-f]+);
  • 空行与以#开头的行(注释)会被忽略;
  • 重复密钥会被自动去重(HashSet);
  • 若文件中存在全零密钥000000000000,则全 F 密钥FFFFFFFFFFFF会被强制放到字典首位优先测试(这是为了规避某些标签/设备的已知 Bug,见源码注释引用的 issue #66)。

第四步:字典攻击式读取原理

MCT 的密钥管理采用基于字典攻击的映射过程。所谓"字典攻击"在此并非破解,而是:用密钥文件(字典)中的每一个密钥,对所有扇区逐一尝试认证(密钥 A 和密钥 B),能认证多少就读取多少。

其实现位于 MCReader.java 的buildNextKeyMapPart():

  1. 依次取出密钥文件中的每个密钥,转换成字节数组;
  2. 对当前扇区先用authenticateSectorWithKeyA()尝试密钥 A,再用authenticateSectorWithKeyB()尝试密钥 B;
  3. 一旦某个扇区的密钥 A 和密钥 B 都被找到,立即停止该扇区的搜索,进入下一个扇区;
  4. 找到的密钥会被记录进"密钥映射表"(mKeyMap,扇区 → 密钥 A/B 的映射);
  5. 为提高效率,已找到的密钥会被移到字典头部优先复用(扇区之间密钥复用非常普遍)。

读取阶段调用readAsMuchAsPossible()(MCReader.java),根据映射表逐个扇区用对应密钥认证并读取全部数据块。读取结果中:

  • 若密钥 B 可读(由访问控制条件决定),扇区尾部会合并出密钥 A 与密钥 B(mergeSectorData());
  • 无法读出的块会以占位符NO_DATA(32 个-)标记,未找到的密钥以NO_KEY(12 个-)标记。

整个"读标签"流程在 ReadTag.java 中完成:先由KeyMapCreator生成密钥映射,再在工作线程中读取,最后生成带+Sector: N分区标记、*No keys found or dead sector错误标记的转储文本,交给DumpEditor展示与编辑。

密钥文件概念的两大优点

原文档强调了两点,这里结合源码再明确一次:

  • 你不必担心哪个密钥属于哪个扇区。应用会尝试使用文件中的所有密钥进行认证(buildNextKeyMapPart()的密钥循环),映射关系完全自动建立。
  • 你不必知道所有密钥。如果在密钥文件(字典)中找不到某扇区的密钥 A 和密钥 B,应用会跳过读取该扇区(映射表中无记录即不读取),而不会报错中断。

正是这种"密钥 ↔ 扇区"的自动映射,让你能用已知密钥轻松读取尽可能多的数据。

转储(Dump)文件与十六进制数据操作

读取结果以"转储文件"形式保存,可通过DumpEditor查看和编辑。转储的格式约定(源码createTagDump()中有明确注释):

  • 扇区头以+Sector: N标记;
  • 无法读取的扇区以*No keys found or dead sector标记;
  • 每个数据块为 16 字节的十六进制字符串。

仓库 tools/example-files/ 提供了转储与密钥文件的格式样例(如 example-dump-file.txt、example-key-dump.txt),可作为手工构造文件的参考。此外 tools/dump-file-converter/ 目录提供eml2mct.py、mfd2eml.py等脚本,用于在 MCT 转储格式与 Proxmark/EML 格式之间互相转换,方便与 PC 端工具链衔接。

许可与致谢

MCT 是自由软件,采用 GNU 通用公共许可证第 3 版(GPLv3) 授权。应用内使用的图标版权声明如下:

  • Logo:Beneke Traub(Creative Commons 4.0);
  • Oxygen Icons:www.oxygen-icons.org(GNU LGPL);
  • RFID Tag 图标:www.nfc-tag.de(Creative Commons 3.0)。

MIFARE® 是 NXP Semiconductors 的注册商标。

相关资源索引

  • 英文版 README:README.md
  • 繁体中文版 README:README.zh-TW.md
  • 应用内置帮助文档:help.html
  • 不兼容设备列表:INCOMPATIBLE_DEVICES.md;兼容设备列表:COMPATIBLE_DEVICES.md
  • 变更日志:CHANGELOG.txt
  • 标准密钥文件:std.keys、extended-std.keys、hotel-std.keys
  • 示例文件:tools/example-files/
  • 格式转换脚本:tools/dump-file-converter/
  • 移动开发

【免费下载链接】MifareClassicTool

An Android NFC app for reading, writing, analyzing, etc. MIFARE Classic RFID tags.

项目地址:https://gitcode.com/gh_mirrors/mi/MifareClassicTool
点击查看免费下载
上一篇:libui 名称保留契约:ui / uipriv 前缀体系与跨平台符号命名规范全解析
下一篇:swagger-codegen 数组模型深入解析:以 Java(Jersey1)客户端 ArrayTest 为例

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询