Mifare DESFire EV1 4K AES身份验证问题



有人能告诉我我做错了什么吗。我必须对我的卡进行AES身份验证。该卡是Mifare DESFire EV1 4K,读卡器是Omnikey 5121。我在Stack上做了一些例子,但在最后一步我总是失败,因为卡的旋转RndA不等于我的旋转RndA。AES配置有问题吗?

public static byte[] Authenticate_AES(this SCardReader reader, byte[] key)
{
using (var aes = Aes.Create())
{
aes.Key = key;
aes.Padding = PaddingMode.None;
aes.Mode = CipherMode.CBC;
aes.BlockSize = 128;
aes.IV = SCardUtils.StringToByteArray("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00");
var decryptor = aes.CreateDecryptor();
var encryptor = aes.CreateEncryptor();
var rnd = new Random();
//Get encrypted RandB from the card
var rAPDU = reader.Transmit(0x90, 0xAA, 0, 0, SCardUtils.StringToByteArray("00"));
if (!rAPDU.HasData)
throw new Exception("RandB_enc is null");
//Encrypted RndB
var RndB_enc = new byte[16];
rAPDU.Data.CopyTo(RndB_enc, 0);
SCardUtils.ShowBytes(RndB_enc, "RndB_enc");
//Decrypt encrypted RndB
var RndB = decryptor.TransformFinalBlock(RndB_enc, 0, RndB_enc.Length);
SCardUtils.ShowBytes(RndB, "RndB");
//Rotate RndB 1 byte to the left
var RndB_rot = SCardUtils.RotateLeft(RndB);
SCardUtils.ShowBytes(RndB_rot, "RndB_rot");
//Generate random RndA
var RndA = new byte[16];
rnd.NextBytes(RndA);
SCardUtils.ShowBytes(RndA, "RndA");
//Concatenate RndA and RndB_rot
var RndAB_rot = RndA.Concat(RndB_rot).ToArray();
SCardUtils.ShowBytes(RndAB_rot, "RndAB_rot");
//Encypt RndAB_rot
var dataToSend = encryptor.TransformFinalBlock(RndAB_rot, 0, RndAB_rot.Length);
SCardUtils.ShowBytes(dataToSend, "Encrypted data");
rAPDU = reader.Transmit(0x90, 0xAF, 0, 0, dataToSend);
if (!rAPDU.HasData)
throw new Exception("rAPDU data is null");
//Encrypted RndA_rot
var RndA_rot_enc = new byte[16];
rAPDU.Data.CopyTo(RndA_rot_enc, 0);
SCardUtils.ShowBytes(RndA_rot_enc, "RndA_rot_enc");
//Decrypt encrypted RndA_rot
var RndA_rot_dec = decryptor.TransformFinalBlock(RndA_rot_enc, 0, RndA_rot_enc.Length);
SCardUtils.ShowBytes(RndA_rot_dec, "RndA_rot_dec");
var RndA_rot = SCardUtils.RotateLeft(RndA);
SCardUtils.ShowBytes(RndA_rot, "RndA_rot");
//Compare RndA_rot with RndA rotated to the left
if (!SCardUtils.IsEqualTo(RndA_rot_dec, RndA_rot))
throw new Exception($"Error authenticating card. The values are not equal.");
var sessionKey = new byte[16];
Array.Copy(RndA, 0, sessionKey, 0, 4);
Array.Copy(RndB, 0, sessionKey, 4, 4);
Array.Copy(RndA, 12, sessionKey, 8, 4);
Array.Copy(RndB, 12, sessionKey, 12, 4);
return sessionKey;
}
}

这是输出:

Reader name:  OMNIKEY CardMan 5x21-CL 0
RndB_enc:     08 DD A2 12 57 43 6C F7 75 98 78 9E 6C 0A A7 06 
RndB:         16 C8 35 7A 4A 36 29 D2 F0 86 26 AD FA CA 81 9F 
RndB_rot:     C8 35 7A 4A 36 29 D2 F0 86 26 AD FA CA 81 9F 16 
RndA:         77 93 A5 8D 0E 0D 88 88 22 C3 40 9C 26 67 95 35 
RndAB_rot:    77 93 A5 8D 0E 0D 88 88 22 C3 40 9C 26 67 95 35 C8 35 7A 4A 36 29 D2 F0 86 26 AD FA CA 81 9F 16 
Data:         4D BD 7A E8 B8 6C 00 5F E4 B5 B5 42 7B AE 51 39 25 77 CB 60 83 6A E8 15 B9 9D FD A9 FD A7 75 9F 
RndA_rot_enc: D6 CB CF 08 5F 8A E8 6C 30 95 34 6F DD CF 4F FA 
RndA_rot_dec: 6B 70 54 39 CD 8E 97 42 E2 A5 FF E3 90 95 46 E0 
RndA_rot:     93 A5 8D 0E 0D 88 88 22 C3 40 9C 26 67 95 35 77

所以你可以看到RndA_rot_dec和RndA_rot不相等,我不知道为什么。

提前谢谢大家。

我终于得到了解决方案。我还对代码进行了一些修改,这样每个像我一样有问题的人都可以更容易地理解它。几个星期。

public static byte[] Authenticate_AES(this SCardReader reader, byte[] key, byte[] IV)
{
//Get encrypted RndB from the tag
var rAPDU = reader.Transmit(0x90, 0xAA, 0, 0, SCardUtils.StringToByteArray("00"));
if (!rAPDU.HasData)
throw new Exception("RandB_enc is null");
var aes = Aes.Create();
aes.Mode = CipherMode.CBC;
aes.KeySize = 128;
aes.BlockSize = 128;
aes.Padding = PaddingMode.None;
aes.Key = key;
aes.IV = IV; //16 bytes of zeros
//Encrypted RndB from the tag
var RndB_enc = rAPDU.Data.ToArray();
SCardUtils.ShowBytes(RndB_enc, "RndB_enc");
var decryptor = aes.CreateDecryptor();
//Decrypt encrypted RndB
var RndB = decryptor.TransformFinalBlock(RndB_enc, 0, RndB_enc.Length);
SCardUtils.ShowBytes(RndB, "RndB");
//Rotate RndB 1 byte to the left
var RndB_rot = SCardUtils.RotateLeft(RndB);
SCardUtils.ShowBytes(RndB_rot, "RndB_rot");
var rnd = new Random();
//Generate random RndA
var RndA = new byte[16];
rnd.NextBytes(RndA);
SCardUtils.ShowBytes(RndA, "RndA");
//Concatenate RndA and RndB_rot
var RndAB_rot = RndA.Concat(RndB_rot).ToArray();
SCardUtils.ShowBytes(RndAB_rot, "RndAB_rot");
//IV is now encrypted RndB received from the tag
aes.IV = RndB_enc;
var encryptor = aes.CreateEncryptor();
//Encypt RndAB_rot
var RndAB_rot_enc = encryptor.TransformFinalBlock(RndAB_rot, 0, RndAB_rot.Length);
SCardUtils.ShowBytes(RndAB_rot_enc, "RndAB_rot_enc");
rAPDU = reader.Transmit(0x90, 0xAF, 0, 0, RndAB_rot_enc);
if (!rAPDU.HasData)
throw new Exception("rAPDU data is null");
//Encrypted RndA_rot from the tag
var RndA_rot_enc = rAPDU.Data.ToArray();
SCardUtils.ShowBytes(RndA_rot_enc, "RndA_rot_enc");
//IV is now the last 16 bytes of RndAB_rot_enc
aes.IV = RndAB_rot_enc.Skip(16).Take(16).ToArray();
decryptor = aes.CreateDecryptor();
//Decrypt encrypted RndA_rot
var RndA_rot = decryptor.TransformFinalBlock(rAPDU.Data, 0, rAPDU.Data.Length);
SCardUtils.ShowBytes(RndA_rot, "RndA_rot");
//Compare RndA_rot_dec with RndA_rot
if (!SCardUtils.IsEqualTo(RndA_rot, SCardUtils.RotateLeft(RndA)))
throw new Exception($"Error authenticating card. The values are not equal.");
var sessionKey = new byte[16];
Array.Copy(RndA, 0, sessionKey, 0, 4);
Array.Copy(RndB, 0, sessionKey, 4, 4);
Array.Copy(RndA, 12, sessionKey, 8, 4);
Array.Copy(RndB, 12, sessionKey, 12, 4);
aes.Clear();
return sessionKey;
}

问题出在Init Vector上。它正在通过三次通过身份验证进行更改。

这是最终输出:

Reader name: OMNIKEY CardMan 5x21-CL 0
RndB_enc: 6F 40 6D 9D 51 7A 2C 9E 88 C9 2C 84 80 94 E3 F7 
RndB: FB FB A7 5F 54 97 D7 CA 4B 15 07 F1 A0 D1 A2 68 
RndB_rot: FB A7 5F 54 97 D7 CA 4B 15 07 F1 A0 D1 A2 68 FB 
RndA: 87 7B BA 48 4D 01 14 CE 4D 8E 33 A5 1B 0F 00 E9 
RndAB_rot: 87 7B BA 48 4D 01 14 CE 4D 8E 33 A5 1B 0F 00 E9 FB A7 5F 54 97 D7 CA 4B 15 07 F1 A0 D1 A2 68 FB 
RndAB_rot_enc: 0B 8B 4E D9 BF 40 51 F0 83 FC 44 E8 B7 A7 21 26 DE A9 B9 CE E5 05 F7 A5 46 FE 91 0F 59 2B 90 E7 
RndA_rot_enc: 9F 3D E8 90 37 2E 7B F6 1E BA AC 29 6E 94 1C 9E 
RndA_rot: 7B BA 48 4D 01 14 CE 4D 8E 33 A5 1B 0F 00 E9 87 

如您所见,向左旋转1字节的RndA(第5行(等于RndA_rot(最后一行(。完成此身份验证。

最新更新