Jak odszyfrować pierwszą wiadomość wysłaną z Mifare Desfire EV1

Czy ktoś ma pojęcie, jak odszyfrować pierwszą wiadomość wysłaną z karty? Mam na myśli po sukcesie uwierzytelniania, a następnie wysyłasz polecenie (na przykład 0x51 (GetRealTagUID). Zwraca 00 + losowe 32 bity (zawsze różne). Próbuję go odszyfrować za pomocą:

        private byte[] decrypt(byte[] raw, byte[] encrypted, byte[] iv)
            throws Exception {
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }

I wywołanie go za pomocą deszyfrowania (sessionKey, response, iv)

IV = wszystkie zera (16 bajtów)

odpowiedź = 32 bity po poleceniu 0x51 (po prostu usunięto dwa zera)

Ktoś powiedział mi, że IV zmienia się po pierwszym wysłanym poleceniu (0x51). Jak wygenerować odpowiednią IV do odszyfrowania tej odpowiedzi? Myślę, że wszystkie zera są błędne, ponieważ odszyfrowana wiadomość jest zawsze inna i zawsze powinna być taka sama z tą samą kartą.

-EDYTOWAĆ-

Po zastosowaniu instrukcji (Michaela Rolanda) odszyfrowana odpowiedź to wciąż tylko losowe bity. Oto mój kod (myślę, że robię coś złego):

            byte[] x = encrypt(sessionKey, iv, iv);

            byte[] rx = rotateBitsLeft(x);

            if ((rx[15] & 0x01) == 0x01)
                rx[15] = (byte) (rx[15] ^ 0x87);

            if ((rx[15] & 0x01) == 0x00)
                rx[15] = (byte) (rx[15] ^ 0x01);

            byte[] crc_k1 = rx;

            byte[] rrx = rotateBitsLeft(rx);

            if ((rrx[15] & 0x01) == 0x01)
                rrx[15] = (byte) (rrx[15] ^ 0x87);

            if ((rrx[15] & 0x01) == 0x00)
                rrx[15] = (byte) (rrx[15] ^ 0x01);

            byte[] crc_k2 = rrx;

            byte[] command = { (byte) 0x51, (byte) 0x80, (byte) 0x00,
                    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                    (byte) 0x00 };

            for (int i = 0; i < 16; i++){
                command[i] = (byte) (command[i] ^ crc_k2[i]);
            }

            byte[] iv2 = encrypt(sessionKey, command, iv);

            byte[] RealUID = decrypt(sessionKey, ReadDataParsed, iv2);

            Log.e("RealUID", ByteArrayToHexString(RealUID));

-EDIT3-

Nadal zawsze zwracam różne wartości. Myślę, że problem może leżeć tutaj:

byte[] iv2 = encrypt(sessionKey, command, iv);

Jakiego IV użyć podczas tworzenia nowego IV do odszyfrowania odpowiedzi? Wszystko tam jest zerowe.

questionAnswers(2)

yourAnswerToTheQuestion