【发布时间】:2025-12-03 02:25:01
【问题描述】:
有没有人知道如何解密从卡发送的第一条消息?我的意思是在身份验证成功之后,然后您发送一个命令(例如 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;
}
并用decrypt(sessionKey, response, iv)调用它
IV = 全零(16 个字节)
response = 0x51 命令后的 32 个随机位(只是去掉了两个零)
有人告诉我,IV 在第一次发送命令 (0x51) 后发生了变化。如何生成正确的 IV 来解密该响应?我认为全零是错误的,因为解密后的消息总是不同的,同一张卡应该总是相同的。
-编辑-
应用您的 (Michael Roland) 指令后,解密的响应仍然只是随机位。这是我的代码(我认为我做错了什么):
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?那里全是零。
【问题讨论】:
-
嗨!你能在哪里完成这项工作?
-
是的 :) 我记得尝试解决这个问题时的两周恐惧。
-
我感觉到你了!很棒的帖子,这是一个救生员!谢谢!
标签: java encryption cryptography aes mifare