authentication - Android:المصادقة باستخدام NXP MiFare Ultralight C




nfc rfid (2)

فيما يلي مثال لشافرة جافا لتنفيذ مصادقة Ultralight-C كما هو موصوف في MF0ICU2 / MIFARE Ultralight C - وثيقة IC غير التلامسية (الفصل 7.5.5 - مصادقة 3DES ، صفحة 15):

public void authenticate(byte[] key) throws CardException {
    System.out.println("AUTHENTICATE");
    byte[] encRndB = transmitRaw(new byte[] { 0x1A, 0x00 });
    if((encRndB.length!=9)||(encRndB[0]!=AF)) {
        throw new RuntimeException("Invalid response!");
    }
    encRndB=Arrays.copyOfRange(encRndB, 1, 9);
    System.out.println(" - EncRndB: " + toHex(encRndB));
    byte[] rndB = desDecrypt(key, encRndB);
    System.out.println(" - RndB: " + toHex(rndB));
    byte[] rndBrot = rotateLeft(rndB);
    System.out.println(" - RndBrot: " + toHex(rndBrot));
    byte[] rndA = new byte[8];
    generateRandom(rndA);
    System.out.println(" - RndA: " + toHex(rndA));
    byte[] encRndArotPrime = transmitRaw(ArrayUtils.addAll(new byte[] {AF}, desEncrypt(key, ArrayUtils.addAll(rndA, rndBrot))));
    if((encRndArotPrime.length!=9)||(encRndArotPrime[0]!=0x00)) {
        throw new RuntimeException("Invalid response!");
    }
    encRndArotPrime=Arrays.copyOfRange(encRndArotPrime, 1, 9);
    System.out.println(" - EncRndArot': " + toHex(encRndArotPrime));
    byte[] rndArotPrime = desDecrypt(key, encRndArotPrime);
    System.out.println(" - RndArot': " + toHex(rndArotPrime));
    if(!Arrays.equals(rotateLeft(rndA), rndArotPrime)) {
        throw new RuntimeException("Card authentication failed");
    }
}

protected static SecureRandom rnd = new SecureRandom();
protected static void generateRandom(byte[] rndA) {
    rnd.nextBytes(rndA);
}

protected byte[] desEncrypt(byte[] key, byte[] data) {
    return performDes(Cipher.ENCRYPT_MODE, key, data);
}
protected byte[] desDecrypt(byte[] key, byte[] data) {
    return performDes(Cipher.DECRYPT_MODE, key, data);
}
private byte[] iv = new byte[8];
protected byte[] performDes(int opMode, byte[] key, byte[] data) {
    try {
        Cipher des = Cipher.getInstance("DESede/CBC/NoPadding");
        SecretKeyFactory desKeyFactory = SecretKeyFactory.getInstance("DESede");
        Key desKey = desKeyFactory.generateSecret(new DESedeKeySpec(ArrayUtils.addAll(key, Arrays.copyOf(key, 8))));
        des.init(opMode, desKey, new IvParameterSpec(iv));
        byte[] ret = des.doFinal(data);
        if(opMode==Cipher.ENCRYPT_MODE) {
            iv=Arrays.copyOfRange(ret, ret.length-8, ret.length);
        } else {
            iv=Arrays.copyOfRange(data, data.length-8, data.length);
        }
        return ret;
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidKeySpecException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
        throw new RuntimeException(e);
    }
}

protected static byte[] rotateLeft(byte[] in) {
    return ArrayUtils.add(Arrays.copyOfRange(in, 1, 8), in[0]);
}

ملاحظة: يستخدم هذا الرمز Apache Commons Lang .

لقد حاولت منذ أكثر من أسبوع أن أصادق هاتف يعمل بنظام Android مع Mifare Ultralight C. لقد أكدت أنني أستطيع الكتابة إلى العلامة (من خلال الكتابة إلى صفحة ذاكرة غير آمنة ثم قراءة ما كتبته). يمكنني أيضاً الكتابة إلى الصفحات الأساسية (44-47) ثم كتابة 0x00 لكافة وحدات البايت الأساسية 16.

عندما أحاول المصادقة ، ما يلي هو مثال على البيانات المتضمنة خلال تبادل واحد - وهو من سجل مكتوب بواسطة التطبيق الخاص بي. هل يمكن لأحد أن يقول لي إذا كنت أفعل شيئًا غير صحيح؟ أنا في حالة عدم الإفصاح ويمكن الوصول إلى أوراق البيانات الكاملة . لاحظ أن السلاسل الست عشرية أدناه هي بوضوح إصدارات بشرية قابلة للقراءة من البيانات التي يتم إرسالها واستلامها ، والتي تتكون في الكود من صفائف البايتات.

أرسل أمر المصادقة

Received rndB: 8A5735694D9D7542

Key: 00000000000000000000000000000000

IV: 0000000000000000

Decrypted rndB: EF340C62E1B866D4

rndB': 340C62E1B866D4EF

rndA: 6E262630E299F94F

rndA+rndB': 6E262630E299F94F340C62E1B866D4EF

Key: 00000000000000000000000000000000

IV: 8A5735694D9D7542

ek(RndA+rndB'): E36C6C46FAAC60BA45DDF5F5A0802C79

بعد إرسال 0xAF + E36C6C46FAAC60BA45DDF5F5A0802C79 الفور تفقد الاتصال مع العلامة. لقد قمت بمراجعة ورقة البيانات وقراءة كل منشور يمكنني العثور عليه هنا. لقد نظرت أيضا في قانون libfreefare وأنا بصراحة لا يمكن معرفة ما أفعله خطأ.

كان الدعم التقني NXP غير مستجيب تمامًا.

أيه أفكار؟ أنا في حيرة.


تحديث: أحدث إصدار من استوديو Android (2.x) أدخل تحسينات كبيرة على المحاكي المجمّع. انها تستجيب ولها مجموعة كاملة من الميزات.

لأولئك الذين ما زالوا مهتمين: حاول استخدام Genymotion . يمكنك تنزيل إصدار لـ Windows / Mac OS X / Linux بعد التسجيل. البرنامج المساعد لل Eclipse هو متاح أيضا:

يمكن أن يتم تثبيت البرنامج عن طريق إطلاق Eclipse والانتقال إلى القائمة "Help / Install New Software" ، ثم إضافة موقع تحديث جديد بعنوان URL التالي: http://plugins.genymotion.com/eclipse . اتبع الخطوات المبينة بواسطة Eclipse.

هذا المحاكي سريع وسريع الاستجابة.

يتيح لك GenyMotion التحكم في العديد من أجهزة الاستشعار في جهازك بما في ذلك مستوى البطارية وقوة الإشارة ونظام تحديد المواقع العالمي. يحتوي الإصدار الأحدث الآن أيضًا على أدوات الكاميرا.





android authentication nfc rfid mifare