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

React Native NFC Manager无法用默认密钥认证Mifare Classic扇区0

解决React Native中react-native-nfc-manager读取Mifare Classic认证失败问题

问题核心原因

你的认证命令缺少卡片UID参数。Mifare Classic的Auth A指令要求完整的命令结构为:0x60(AuthA) + 块地址 + 6字节密钥 + 4字节卡片UID,你的代码中仅构造了前三个部分,缺少UID导致认证失败。

修改方案

1. 转换卡片UID为字节数组

在读取到tag后,将tag.id(十六进制字符串格式)转换为Uint8Array格式的UID字节数组。

2. 补全认证命令参数

修改认证函数,将UID加入到认证命令中;同时建议使用扇区的控制块(每个扇区的最后一个块)进行认证,这是Mifare Classic的标准做法。

3. 优化错误调试

在catch中打印具体错误信息,便于排查问题。

修改后的完整代码

NFCManagerService.ts

import NfcManager, { NfcTech } from 'react-native-nfc-manager';

class NFCManagerService {
    private static instance: NFCManagerService;

    private readonly CMD = {
        AUTH_A: 0x60, // Authenticate with Key A
        READ: 0x30,   // Read block
    };

    private constructor() { }

    public static getInstance(): NFCManagerService {
        if (!NFCManagerService.instance) {
            NFCManagerService.instance = new NFCManagerService();
        }
        return NFCManagerService.instance;
    }

    public async readSectorZero(logCallback: (message: string) => void): Promise<void> {
        try {
            logCallback('Initializing NFC...');
            await NfcManager.requestTechnology(NfcTech.MifareClassic);
            logCallback('NFC initialized.');

            const tag = await NfcManager.getTag();
            if (!tag || !tag.id) {
                throw new Error('No tag detected or tag ID missing.');
            }
            logCallback(`Tag detected: ${tag.id}`);

            // 将十六进制字符串格式的UID转换为字节数组
            const uidBytes = Uint8Array.from(
                tag.id.match(/.{1,2}/g)!.map(byte => parseInt(byte, 16))
            );
            const key = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
            const keyHex = key.map(b => b.toString(16).padStart(2, '0')).join('');
            logCallback(`Attempting Auth A Sector 0 with key: ${keyHex}`);

            if (await this.authenticateSector(0, key, uidBytes, logCallback)) {
                logCallback(`✓ Auth A Sector 0 succeeded with key: ${keyHex}`);

                const data = await this.readBlock(0);
                if (data) {
                    logCallback(`Data from Block 0: ${Array.from(data).map(b => b.toString(16).padStart(2, '0')).join(' ')}`);
                } else {
                    logCallback('Failed to read data from Block 0.');
                }
            } else {
                logCallback(`✗ Auth A Sector 0 failed with key: ${keyHex}`);
            }
        } catch (error) {
            logCallback(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
        } finally {
            await NfcManager.cancelTechnologyRequest();
            logCallback('NFC released.');
        }
    }

    private async authenticateSector(sector: number, key: number[], uid: Uint8Array, logCallback: (message: string) => void): Promise<boolean> {
        try {
            // 使用扇区的控制块(每个扇区最后一个块)进行认证,扇区0的控制块是3
            const blockIndex = sector * 4 + 3;
            const authCommand = [this.CMD.AUTH_A, blockIndex, ...key, ...uid];
            const response = await NfcManager.transceive(authCommand);
            logCallback(`Auth response: ${Array.from(response).map(b => b.toString(16).padStart(2, '0')).join(' ')}`);
            return true;
        } catch (error) {
            logCallback(`Auth error details: ${JSON.stringify(error)}`);
            return false;
        }
    }

    private async readBlock(blockIndex: number): Promise<Uint8Array | null> {
        try {
            const readCommand = [this.CMD.READ, blockIndex];
            const response = await NfcManager.transceive(readCommand);
            return new Uint8Array(response);
        } catch (error) {
            console.error('Read block error:', error);
            return null;
        }
    }
}

export default NFCManagerService;

额外排查点

  • 权限配置:确保AndroidManifest.xml中添加了NFC权限及相关intent-filter,iOS的Info.plist中配置了NFCUsageDescription。
  • UID字节序:部分设备返回的tag.id字节序可能与卡片实际UID相反,可对比Mifare Classic Tool中的UID,调整转换逻辑。
  • 库版本:确保react-native-nfc-manager为最新稳定版,避免库本身的兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 20:39:54