news 2026/5/4 8:18:23

用Arduino和RC522模块DIY一个NFC门禁卡复制器(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Arduino和RC522模块DIY一个NFC门禁卡复制器(附完整代码)

用Arduino和RC522模块打造智能NFC卡复制工具

周末整理抽屉时翻出一沓旧门禁卡,突然想到能否用手头的电子元件做个卡片复制工具。这个想法让我兴奋不已——毕竟谁不想体验一把"科技魔法"呢?本文将带你用最常见的Arduino开发板和RC522模块,打造一个成本不到百元的NFC卡复制器。无论你是想备份自己的门禁卡,还是单纯对射频技术感兴趣,这个项目都能让你在动手实践中收获满满。

1. 硬件准备与连接

工欲善其事,必先利其器。我们需要准备的硬件非常简单:

  • Arduino Uno开发板(约30元)
  • RC522 NFC读写模块(约15元)
  • 杜邦线若干(公对母)
  • 空白M1卡或UID可改写卡(约2元/张)

RC522模块背面通常标注着清晰的引脚定义,我们需要重点关注以下6个接口:

模块引脚Arduino引脚功能说明
SDAD10片选信号
SCKD13时钟信号
MOSID11主机输出
MISOD12主机输入
IRQ不接中断信号
GNDGND地线
RSTD9复位
3.3V3.3V电源

注意:虽然RC522支持5V供电,但使用3.3V更为安全稳定。连接时建议先断电操作,避免短路风险。

硬件组装只需三步:

  1. 将RC522的SPI接口对应连接到Arduino
  2. 接好复位和片选引脚
  3. 最后连接电源线

检查无误后上电,模块上的红色LED应常亮,表示供电正常。如果使用带天线的版本,注意不要弯折天线线圈,这会影响读写距离。

2. 软件环境配置

在开始编程前,我们需要准备Arduino IDE和必要的库文件。最新版的Arduino IDE(2.3.x)已经内置了不错的库管理功能:

  1. 打开IDE,点击"工具"->"管理库"
  2. 搜索并安装"MFRC522"库(作者Miguel Balboa)
  3. 同时建议安装"SPI"库(Arduino官方)

安装完成后,新建一个空白项目。我们先测试硬件是否正常工作:

#include <SPI.h> #include <MFRC522.h> #define RST_PIN 9 #define SS_PIN 10 MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); Serial.println("Ready to read cards..."); } void loop() { if (!mfrc522.PICC_IsNewCardPresent()) return; if (mfrc522.PICC_ReadCardSerial()) { Serial.print("Card UID:"); for (byte i = 0; i < mfrc522.uid.size; i++) { Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(mfrc522.uid.uidByte[i], HEX); } Serial.println(); mfrc522.PICC_HaltA(); } }

上传代码后打开串口监视器(波特率9600),当用卡片靠近模块时,应该能看到类似这样的输出:

Card UID: 3A 2B 1C 4D

这表示我们已经成功读取到卡的UID(唯一标识符)。如果遇到问题,可以检查:

  • 接线是否正确,特别是SPI接口
  • 库文件是否安装正确
  • 卡片是否支持13.56MHz频率

3. NFC卡数据读取详解

成功读取UID只是第一步,M1卡的数据存储结构才是关键所在。标准的M1卡有1KB存储空间,分为16个扇区,每个扇区包含4个块(block),每个块16字节。存储结构如下:

扇区0 ├─ Block 0: 厂商信息(只读) ├─ Block 1: 数据块 ├─ Block 2: 数据块 └─ Block 3: 密钥A(6B)+控制位(4B)+密钥B(6B) ...(扇区1-15结构相同)

读取完整卡数据的核心代码如下:

void dumpCardData() { MFRC522::MIFARE_Key key; for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; // 默认密钥 for (byte sector = 1; sector < 16; sector++) { // 跳过扇区0 if (mfrc522.PICC_Authenticate( MFRC522::PICC_CMD_MF_AUTH_KEY_A, sector * 4, &key, &(mfrc522.uid)) != MFRC522::STATUS_OK) { Serial.print("Auth failed for sector "); Serial.println(sector); continue; } for (byte block = 0; block < 3; block++) { // 只读数据块 byte buffer[18]; byte size = sizeof(buffer); if (mfrc522.MIFARE_Read(sector * 4 + block, buffer, &size) != MFRC522::STATUS_OK) { Serial.print("Read failed for block "); Serial.println(sector * 4 + block); continue; } Serial.print("Sector "); Serial.print(sector); Serial.print(" Block "); Serial.print(block); Serial.print(" : "); for (byte i = 0; i < 16; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } Serial.println(); } } }

这段代码会尝试用默认密钥(FFFFFFFFFFFF)读取所有扇区的数据块。实际应用中可能会遇到:

  • 加密扇区:返回认证错误(STATUS_CODE ≠ 0)
  • 损坏块:读取超时或返回异常数据
  • 特殊格式数据:如门禁系统可能使用特定格式存储用户ID

重要提示:频繁读取卡片可能导致某些系统标记为异常卡。建议在测试时使用空白卡或无关紧要的卡片。

4. 卡片复制实战操作

成功读取原卡数据后,我们需要准备一张UID可改写卡(CUID卡)进行复制。普通M1卡的UID是只读的,而CUID卡允许修改前4/7/10字节的UID。

复制流程分为三个关键步骤:

  1. UID写入(仅CUID卡需要):
void writeUID(byte* newUID, byte uidSize) { if (mfrc522.PICC_WriteCardSerial(newUID, uidSize)) { Serial.println("UID写入成功"); } else { Serial.println("UID写入失败"); } }
  1. 数据块写入
bool writeBlock(byte sector, byte block, byte* data) { MFRC522::MIFARE_Key key; for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; if (mfrc522.PICC_Authenticate( MFRC522::PICC_CMD_MF_AUTH_KEY_A, sector * 4 + 3, &key, &(mfrc522.uid)) != MFRC522::STATUS_OK) { return false; } return mfrc522.MIFARE_Write(sector * 4 + block, data, 16) == MFRC522::STATUS_OK; }
  1. 数据验证
void verifyData(byte sector, byte block, byte* expected) { byte buffer[18]; byte size = sizeof(buffer); if (mfrc522.MIFARE_Read(sector * 4 + block, buffer, &size) == MFRC522::STATUS_OK) { bool match = true; for (byte i = 0; i < 16; i++) { if (buffer[i] != expected[i]) { match = false; break; } } Serial.print("验证结果: "); Serial.println(match ? "成功" : "失败"); } }

完整复制流程建议按照以下顺序操作:

  1. 读取原卡所有可读扇区数据
  2. 将CUID卡置于读卡区
  3. 写入UID(与原卡一致)
  4. 逐个扇区写入数据
  5. 对每个写入块进行验证
  6. 测试复制卡是否可用

常见问题处理:

  • 写入失败:检查卡片是否支持写入,尝试降低SPI时钟速度
  • 部分扇区无法复制:可能是加密扇区,需要获取密钥
  • 复制卡无法使用:检查控制位是否复制正确,某些系统会检测卡片类型

5. 安全与伦理考量

在享受技术带来的便利时,我们必须清醒认识到:未经授权复制他人卡片可能涉及法律问题。这里分享几个实际项目中的经验教训:

去年帮小区物业测试门禁系统时发现,他们的卡片居然全部使用默认密钥。虽然我立即报告了这个漏洞,但也意识到如果被别有用心的人利用后果不堪设想。因此建议:

  • 仅复制自己拥有权限的卡片
  • 企业用户应定期更换密钥
  • 重要系统应采用CPU卡等更安全的方案

技术本身无罪,关键在于使用者的意图。这个项目最适合的应用场景其实是:

  • 制作备份卡防止原卡丢失
  • 开发智能家居门禁系统
  • 学习射频识别技术原理
  • 创建多功能合一卡(如门禁+公交卡)

对于想深入研究的开发者,可以尝试以下方向:

  1. 加密破解:通过暴力破解或侧信道攻击获取密钥(仅限合法研究)
  2. 数据解析:分析不同系统的数据存储格式
  3. 系统集成:将读卡器接入Home Assistant等智能家居平台
  4. 安全增强:开发带二次验证的读卡系统

最后提醒:某些新款门禁卡采用动态加密或CPU卡技术,无法用本文方法复制。如果遇到复制后无法使用的情况,很可能就是这类高级卡片。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/4 8:17:26

终极指南:5分钟配置Zotero SciPDF插件实现学术文献自动下载

终极指南&#xff1a;5分钟配置Zotero SciPDF插件实现学术文献自动下载 【免费下载链接】zotero-scipdf Download PDF from Sci-Hub automatically For Zotero7 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-scipdf Zotero SciPDF是一款专为Zotero 7设计的智能文…

作者头像 李华
网站建设 2026/5/4 8:15:28

神经检索模型中的MW损失函数设计与实践

1. 项目背景与核心价值 在信息检索领域&#xff0c;神经检索模型近年来已成为提升搜索质量的关键技术。传统检索模型主要依赖词频统计和浅层语义匹配&#xff0c;而神经检索通过深度神经网络捕捉查询和文档间的复杂语义关系&#xff0c;显著提升了搜索相关性。然而&#xff0c;…

作者头像 李华
网站建设 2026/5/4 8:14:42

小红书无水印下载工具:3步实现高效内容采集

小红书无水印下载工具&#xff1a;3步实现高效内容采集 【免费下载链接】XHS-Downloader 小红书&#xff08;XiaoHongShu、RedNote&#xff09;链接提取/作品采集工具&#xff1a;提取账号发布、收藏、点赞、专辑作品链接&#xff1b;提取搜索结果作品、用户链接&#xff1b;采…

作者头像 李华
网站建设 2026/5/4 8:14:32

告别手动拣货:如何用SAP EWM的仓库处理类型(WPT)自动化你的出库流程

告别手动拣货&#xff1a;SAP EWM仓库处理类型(WPT)的自动化革命 在快节奏的现代供应链环境中&#xff0c;仓库运营效率直接决定了企业的市场响应速度。传统手动拣货流程不仅耗时费力&#xff0c;还容易因人为因素导致错误和延误。SAP Extended Warehouse Management (EWM) 作…

作者头像 李华