Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update example - Cannot authenticate sector #762

Open
Sosotess93 opened this issue Dec 1, 2024 · 1 comment
Open

Update example - Cannot authenticate sector #762

Sosotess93 opened this issue Dec 1, 2024 · 1 comment

Comments

@Sosotess93
Copy link

Sosotess93 commented Dec 1, 2024

Hello,

I'm trying to use this package (I'm new in react-native).
I do have an rfid tag with the standard key FFFFFFFFFFFF, I'm trying to authenticate using your example or what I read but that doesn’t work.

I'm using the latest version : [email protected]

I'm trying to authenticate the sector 0 with the standard key.
I know this is the key as I tried many different app included MifareClassicTool and it works and gave me that key.
It keep failing so if someone can help me.

When I'm trying your example that doesn't work at all as it doesn't find some functions.

Can you tell me what I did wrong and how can I fix that please ?

I do have an easy app at the moment with one button (ReaderScreen) :

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([]); // Réinitialiser les logs
        try {
            const nfcService = NFCManagerService.getInstance();
            await nfcService.readSectorZero(addLog);
        } catch (error) {
            addLog('Erreur lors de la lecture du badge.');
        } finally {
            setIsReading(false);
        }
    };

    return (
        <View style={styles.container}>
            <Button
                title={isReading ? 'Lecture en cours...' : 'Lire le Secteur 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;

And my NFCManagerService :

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

class NFCManagerService {
    private static instance: NFCManagerService;

    private readonly CMD = {
        AUTH_A: 0x60, // Commande pour Authentification avec clé A
        READ: 0x30,   // Commande pour lire un bloc
    };

    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 {
            // Initialiser le NFC
            logCallback('Initialisation du NFC...');
            await NfcManager.requestTechnology(NfcTech.MifareClassic);
            logCallback('NFC initialisé.');

            // Vérifier si un tag est détecté
            const tag = await NfcManager.getTag();
            if (!tag) {
                throw new Error('Aucun badge détecté.');
            }
            logCallback(`Badge détecté : ${tag.id}`);

            // Clé à tester (FFFFFFFFFFFF)
            const key = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
            const keyHex = key.map(b => b.toString(16).padStart(2, '0')).join('');
            logCallback(`Tentative Auth A Secteur 0 avec clé: ${keyHex}`);

            // Authentification pour le secteur 0
            if (await this.authenticateSector(0, key)) {
                logCallback(`✓ Auth A Secteur 0 réussie avec clé: ${keyHex}`);

                // Lecture du premier bloc
                const data = await this.readBlock(0);
                if (data) {
                    logCallback(`Données du bloc 0 : ${Array.from(data).map(b => b.toString(16).padStart(2, '0')).join(' ')}`);
                } else {
                    logCallback('Impossible de lire les données du bloc 0.');
                }
            } else {
                logCallback(`✗ Auth A Secteur 0 échouée avec clé: ${keyHex}`);
            }
        } catch (error) {
            const errorMessage = error instanceof Error ? error.message : 'Erreur inconnue';
            logCallback(`Erreur : ${errorMessage}`);
        } finally {
            // Libérer la technologie NFC
            await NfcManager.cancelTechnologyRequest();
            logCallback('NFC libéré.');
        }
    }

    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; // Authentification réussie
        } catch (error) {
            return false; // Authentification échouée
        }
    }

    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) {
            return null; // Erreur de lecture
        }
    }
}

export default NFCManagerService;
@javix64
Copy link
Collaborator

javix64 commented Dec 24, 2024

Hi @Sosotess93, the key format is not correct.
I do not know which line is it in your code, but you wrote:

const key = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
            const keyHex = key.map(b => b.toString(16).padStart(2, '0')).join('');
            logCallback(`Tentative Auth A Secteur 0 avec clé: ${keyHex}`);

            // Authentification pour le secteur 0
            if (await this.authenticateSector(0, key)) {

(I was writing this and i notice that you did not even use keyHex, you are using key that has: 0xff..., which is wrong)

The value returned by keyHex is: "ffffffffffff" which is not correct.
Key must be: number[]. This is, an array of numbers. In your case is: [255, 255, 255, 255, 255, 255] this is the key that you need for authentication.

I will refer you to check index.d.ts:

mifareClassicAuthenticateA: (
      sector: number,
      keys: number[],
    ) => Promise<void>;
    mifareClassicAuthenticateB: (
      sector: number,
      keys: number[],
    ) => Promise<void>;

To be honest i had never use before commands and transceives for communicate with a tag. use the classic mifareClassicReadBlock or another functions... (my recommendation)

I do not know if I explain myself good, but let me know and I can help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants