我正在开发一个React Native项目,使用react-native-nfc-manager库读取NFC Mifare Classic卡。我的目标是使用默认的 Mifare Classic 密钥 FFFFFFFFFFFF 验证并读取扇区 0 中的数据。然而,即使我知道密钥是正确的(它与 Mifare Classic Tool 和我以前的 Java 应用程序等其他应用程序一起使用),我的 React Native 实现始终无法进行身份验证。
我尝试过的 这是我对扇区 0 读取的实现:
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) {
throw new Error('No tag detected.');
}
logCallback(`Tag detected: ${tag.id}`);
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)) {
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[]): Promise<boolean> {
try {
const authCommand = [this.CMD.AUTH_A, sector * 4, ...key];
await NfcManager.transceive(authCommand);
return true;
} catch {
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 {
return null;
}
}
}
export default NFCManagerService;
ReaderScreen.tsx
import React, { useState } from 'react';
import { View, Button, Text, ScrollView, StyleSheet } from 'react-native';
import NFCManagerService from '../services/NFCManagerService';
const ReaderScreen = () => {
const [logs, setLogs] = useState<string[]>([]);
const [isReading, setIsReading] = useState(false);
const addLog = (message: string) => {
setLogs(prevLogs => [...prevLogs, message]);
};
const handleReadSectorZero = async () => {
setIsReading(true);
setLogs([]);
try {
const nfcService = NFCManagerService.getInstance();
await nfcService.readSectorZero(addLog);
} catch {
addLog('Error reading the badge.');
} finally {
setIsReading(false);
}
};
return (
<View style={styles.container}>
<Button
title={isReading ? 'Reading...' : 'Read Sector 0'}
onPress={handleReadSectorZero}
disabled={isReading}
/>
<ScrollView style={styles.logContainer}>
{logs.map((log, index) => (
<Text key={index} style={styles.logText}>{log}</Text>
))}
</ScrollView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
logContainer: {
marginTop: 20,
maxHeight: 400,
width: '100%',
backgroundColor: '#f4f4f4',
padding: 10,
borderRadius: 8,
},
logText: {
fontSize: 14,
marginBottom: 5,
},
});
export default ReaderScreen;
问题:
我可以使用 NfcManager.transceive 检测卡并发送命令。 该卡是一张空白 Mifare Classic 1K,扇区 0 应该可以使用默认密钥 FFFFFFFFFFFF 读取。 同一张卡和钥匙与 Mifare Classic Tool 应用程序完美配合。 这是我的应用程序尝试身份验证时的日志:
有人可以知道答案或者我做错了什么吗?