ACR122U-A9 读取NFC卡7字节UID

如何解决ACR122U-A9 读取NFC卡7字节UID

我有一张 mifare Ultralight EV1 卡,它根据文档支持 7 字节 UID,但是当我使用 Buffer 读取它时。 from([0xFF,0xCA,0x00,0x00] 我只从 APDT 命令得到四个字节。

关于如何获取完整 7 个字节的任何要点,当我使用 android 或 iOS 阅读器时,他们获取完整的 7 个字节 UID,也许扫描仪不支持它?

这是用安卓手机扫描的卡片:

enter image description here

这是我使用的代码: 也作为 Pastebin 在这里https://pastebin.com/uaaqX7e6

var pcsc = require('pcsclite');

var pcsc = pcsc();
pcsc.on('reader',function(reader) {

    console.log('New reader detected',reader.name);

    reader.on('error',function(err) {
        console.log('Error(',this.name,'):',err.message);
    });

    reader.on('status',function(status) {
        // console.log('Status(',status);
        /* check what has changed */
        var changes = this.state ^ status.state;
        if (changes) {
            if ((changes & this.SCARD_STATE_EMPTY) && (status.state & this.SCARD_STATE_EMPTY)) {
                console.log("card removed");/* card removed */
                reader.disconnect(reader.SCARD_LEAVE_CARD,function(err) {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log('disconnected');
                    }
                });
            } else if ((changes & this.SCARD_STATE_PRESENT) && (status.state & this.SCARD_STATE_PRESENT)) {
                console.log("card inserted");/* card inserted */
                reader.connect({ share_mode : this.SCARD_SHARE_SHARED },function(err,protocol) {
                    if (err) {
                        console.log(err);
                    } else {
                        // console.log('Protocol(',reader.name,protocol);
                        // reader.transmit(Buffer.from([0x1B,0xFF,0xFF]),40,protocol,data) {
                        //     if (err) {
                        //         console.log(err);
                        //     } else {
                        //         console.log('Data received',data);
                        //         //reader.close();
                        //         //pcsc.close();
                        //     }
                        // });

                        // const packet = new Buffer.from([
                        //     0xff,// Class
                        //     0xca,// INS
                        //     0x00,// P1: Get current card UID
                        //     0x00,// P2
                        //     0x00  // Le: Full Length of UID
                        //   ]);

                          const packet = new Buffer.from([
                            0xff,// Class
                            0xb0,// INS
                            0x00,// P1: Get current card UID
                            0x00,// P2
                            0x00  // Le: Full Length of UID
                          ]);
                          
                        //   reader.transmit(packet,12,(err,response) => {
                          
                        //     if (err) {
                        //       console.log(err);
                        //       return;
                        //     }
                          
                        //     if (response.length < 2) {
                        //       console.log(`Invalid response length ${response.length}. Expected minimal length was 2 bytes.`);
                        //       return;
                        //     }
                          
                        //     // last 2 bytes are the status code
                        //     const statusCode = response.slice(-2).readUInt16BE(0);
                          
                        //     // an error occurred
                        //     if (statusCode !== 0x9000) {
                        //       console.log('Could not get card UID.');
                        //       return;
                        //     }
                          
                        //     // strip out the status code (the rest is UID)
                        //     const uid = response.slice(0,-2).toString('hex');
                        //     // const uidReverse = reverseBuffer(response.slice(0,-2)).toString('hex'); // reverseBuffer needs to be implemented
                          
                        //     console.log('card uid is',uid);
                          
                        //   });

                        reader.transmit(packet,data) {
                            if (err) {
                                console.log(err);
                            } else {
                                console.log('Data received',data);
                                //reader.close();
                                //pcsc.close();
                            }
                        });
                    }
                });
            }
        }
    });

    reader.on('end',function() {
        console.log('Reader','removed');
    });
});

pcsc.on('error',function(err) {
    console.log('PCSC error',err.message);
});

解决方法

一种方法是读取二进制块 0 和 1

例如 APDU = {FF B0 00 00 08}

字节 0、1、2、4、5、6、7 将是 7 字节的 UID。

更新

该命令改编自 ACR122U manual

在第 5.3 节中

从二进制页面 04h (MIFARE Ultralight) 中读取 4 个字节

APDU = {FF B0 00 04 04h}

从二进制页面 04h (MIFARE Ultralight) 开始读取 16 个字节(将读取第 4、5、6 和 7 页)

APDU = {FF B0 00 04 10h}

遗憾的是,此读卡器不完全支持符合 NFC Forum Type 2 的卡(例如 Mifare Ultralight C)或兼容 NFC Forum Type 2 的卡(例如 Mifare Ultralight EV1),它仅完全支持读取 Mifare Classic 卡,尽管有一些这3种卡片的共性,所以你应该可以做一些操作

一个区别是 UID 的大小与原来的 Mifare Classic 有一个 4 字节的 UID,另一个是身份验证。

对于 Mifare Ultralight EV1 读取次数超过一次块,您参考的文档表明此功能有点依赖于实际硬件。

我建议您尝试发送:

FF B0 00 00 00 读取块 00

FF B0 00 01 00 读取块 01

单独读取 2 个块中的每一个

始终支持您的文档所说的适用于 NFC 类型 2 卡的方法。

Mifare Ultralight EV1 的 UID 是 Block 00 的字节 0,1,2,然后是 Block 01 的字节 0,2,3

更新 2

不幸的是,我不是该特定读卡器硬件的专家,但答案的主要部分是,根据卡的数据表,卡的 UID 也存储在块 0 和 1 的内存中{ {3}}

如果您在“其他”选项卡中使用 NFC 工具的“读取内存”选项,它将在块 0 和 1 中列出 UID

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?