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

如何使用Node.js访问符合ISO14443A标准的Mifare智能卡

使用Node.js读取Omnikey 5321 CL读卡器上ISO14443A标准Mifare卡的实现方案

前置依赖准备

  • 先安装Omnikey 5321 CL官方驱动,确保系统正常识别读卡器设备
  • 安装PC/SC标准的Node.js绑定库@pokusew/pcsclite,该库原生支持ISO14443A协议的Mifare卡操作:npm install @pokusew/pcsclite
  • Linux系统需提前安装pcscd服务和libpcsclite-dev依赖包

核心实现逻辑

你提到的三个参数会分别在选应用、块认证环节传入,可参考以下可运行代码,按实际参数替换对应变量即可:

const pcsclite = require('@pokusew/pcsclite');
const pcsc = pcsclite();

// 以下参数按实际场景替换
const AID = Buffer.from('F00102', 'hex'); // 3位十六进制格式Application ID,示例为F00102
const KEY = Buffer.from([0x12, 0x34, 0x56, 0x78]); // 32位整数格式密钥,转换为4字节Buffer传入
const KEY_ID = 0x60; // 十六进制格式keyid,Mifare卡通用密钥A为0x60、密钥B为0x61
const TARGET_BLOCK = 0x04; // 需要读取的卡块编号,按需调整

pcsc.on('reader', (reader) => {
    console.log('已识别读卡器:', reader.name);

    reader.on('status', (status) => {
        const stateChange = reader.state ^ status.state;
        // 检测到卡片插入
        if (stateChange & reader.SCARD_STATE_PRESENT) {
            console.log('检测到Mifare卡插入');
            reader.connect({ share_mode: reader.SCARD_SHARE_SHARED }, (err, protocol) => {
                if (err) {
                    console.error('卡片连接失败:', err);
                    return;
                }

                // 第一步:选择指定AID的应用
                const selectApdu = Buffer.concat([
                    Buffer.from([0x00, 0xA4, 0x04, 0x00]),
                    Buffer.from([AID.length]),
                    AID
                ]);
                reader.transmit(selectApdu, 256, protocol, (err, res) => {
                    if (err || res.slice(-2).toString('hex') !== '9000') {
                        console.error('AID选择失败:', err || '响应码异常' + res.slice(-2).toString('hex'));
                        return;
                    }
                    console.log('AID选择成功');

                    // 第二步:使用指定密钥和keyid认证目标块
                    const authApdu = Buffer.concat([
                        Buffer.from([0xFF, 0x86, 0x00, 0x00, 0x05]),
                        Buffer.from([0x01, 0x00, TARGET_BLOCK, KEY_ID, 0x00]),
                        KEY
                    ]);
                    reader.transmit(authApdu, 256, protocol, (err, res) => {
                        if (err || res.slice(-2).toString('hex') !== '9000') {
                            console.error('块认证失败:', err || '响应码异常' + res.slice(-2).toString('hex'));
                            return;
                        }
                        console.log('块认证成功');

                        // 第三步:读取目标块数据
                        const readApdu = Buffer.from([0xFF, 0xB0, 0x00, TARGET_BLOCK, 0x10]);
                        reader.transmit(readApdu, 256, protocol, (err, res) => {
                            if (err || res.slice(-2).toString('hex') !== '9000') {
                                console.error('块读取失败:', err || '响应码异常' + res.slice(-2).toString('hex'));
                                return;
                            }
                            // 输出读取到的16字节块数据,去掉末尾2字节状态码
                            const blockData = res.slice(0, -2).toString('hex');
                            console.log('读取到的块数据:', blockData);

                            // 操作完成断开连接
                            reader.disconnect(reader.SCARD_LEAVE_CARD, () => {});
                        });
                    });
                });
            });
        }
    });
});

pcsc.on('error', (err) => {
    console.error('PCSC服务异常:', err);
});

注意事项

  • 32位整数密钥转换为Buffer时需要注意和卡片要求的字节序一致,默认按大端转换即可
  • 若认证失败,优先检查密钥正确性、目标块是否有对应密钥的读取权限
  • 不同厂商的专用Mifare卡可能会有自定义APDU指令,若通用指令不生效可参考厂商提供的卡片接口文档调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:06:04