Как расшифровать первое сообщение, отправленное с Mifare Desfire EV1
У кого-нибудь есть подсказка, как расшифровать первое сообщение, отправленное с карты? Я имею в виду после успешной аутентификации, а затем вы отправляете команду (например, 0x51 (GetRealTagUID). Она возвращает 00 + random32bits (всегда разные). Я пытаюсь расшифровать его с помощью:
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;
}
И вызывая его с расшифровкой (sessionKey, response, iv)
IV = все нули (16 байтов)
response =, что 32ndombits после команды 0x51 (только что удалили два нуля)
Кто-то сказал мне, что IV меняется после первой отправленной команды (0x51). Как создать правильный IV для расшифровки этого ответа? Я думаю, что все нули неверны, потому что дешифрованное сообщение всегда отличается и должно быть всегда одинаковым для одной и той же карты.
-РЕДАКТИРОВАТЬ-
После применения ваших инструкций (Майкл Роланд) расшифрованный ответ все еще остается случайным битом. Вот мой код (я думаю, что я делаю что-то не так):
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-
Все еще возвращаю всегда разные значения. Я думаю, что проблема может лежать здесь:
byte[] iv2 = encrypt(sessionKey, command, iv);
Какой IV использовать при создании нового IV для расшифровки ответа? Там все нули.