对不起我的英语很糟糕 :) 但这不是我的母语。我是俄罗斯人。
首先检查数组[0]的最高有效位(MSB)是否为1;之后将其向左移动,然后将其与0x01进行异或;
或者在移位后将数组[0]的第一个MSB位保存下来,然后将此位放置在数组[15]的末尾(LSB位)。
请参考以下链接:
https://www.nxp.com/docs/en/application-note/AN10922.pdf
请尝试以下方式:
Zeros <- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SessionKey <- 00 01 02 03 E3 27 64 0C 0C 0D 0E 0F 5C 5D B9 D5
Data <- 6F 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00
首先需要使用SesionKey加密16个字节(zeros)。
enc_aes_128_ecb(Zeros);
您会得到加密数据。
加密数据 <- 3D 08 A2 49 D9 71 58 EA 75 73 18 F2 FA 6A 27 AC
检查加密数据的第一个字节的第7位(从最高位到最低位)是否等于1?如果是,将i开关设置为true。
bool i = false;
if (EncryptedData[0] & 0x80){
i = true;
}
然后将所有加密数据向左移动1位 <<。
ShiftLeft(EncryptedData,16);
现在,当i == true时 - 将最后一个字节[15]与0x87进行异或操作
if (i){
ShiftedEncryptedData[15] ^= 0x87;
}
7A 11 44 93 B2 E2 B1 D4 EA E6 31 E5 F4 D4 4F 58
请将其保存为KEY_1。
尝试判断ShiftedEncryptedData[0]的第7位[从高到低]是否等于1?
i = false
if (ShiftedEncryptedData[0] & 0x80){
i = true
}
然后将所有ShiftedEncryptedData向左移动1位。
ShiftLeft(ShiftedEncryptedData,16);
现在,当i等于true时 - 将最后一个字节[15]与0x87进行异或操作
if (i){
ShiftedEncryptedData[15] ^= 0x87;
}
F4 22 89 27 65 C5 63 A9 D5 CC 63 CB E9 A8 9E B0
将其保存为KEY_2。
现在我们需要处理数据(6F80 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
按照Michael的说法,用0x80 0x00填充命令...
使用KEY_2对数据进行异或运算 - 如果命令已被填充,则使用KEY_1。
如果有超过16个字节(例如32个),则只需对最后16个字节进行异或运算。
然后加密它:
enc_aes_128_ecb(Data);
现在你有一个CMAC。
CD C0 52 62 6D F6 60 CA 9B C1 09 FF EF 64 1A E3
Zeros <- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SessionKey <- 00 01 02 03 E3 27 64 0C 0C 0D 0E 0F 5C 5D B9 D5
Key_1 <- 7A 11 44 93 B2 E2 B1 D4 EA E6 31 E5 F4 D4 4F 58
Key_2 <- F4 22 89 27 65 C5 63 A9 D5 CC 63 CB E9 A8 9E B0
Data <- 6F 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00
CMAC <- CD C0 52 62 6D F6 60 CA 9B C1 09 FF EF 64 1A E3
C/C++函数:
void ShiftLeft(byte *data, byte dataLen){
for (int n = 0; n < dataLen - 1; n++) {
data[n] = ((data[n] << 1) | ((data[n+1] >> 7)&0x01));
}
data[dataLen - 1] <<= 1;
}
祝您有美好的一天 :)