有没有人能通过使用这个芯片的超轻C卡获得相互认证?我理解身份验证过程,但是看看芯片手册中的命令集,并尝试了一些我认为实际上不可能的事情,但我想在放弃芯片组并重新使用CJS编码器进行验证之前,我应该在这里发布。
提前感谢
发布于 2017-03-17 13:54:21
是的,可以与Mifare Ultralight C执行相互身份验证。请使用以下步骤:
步骤1:发送开始身份验证命令。(1A 00)转往卡
步骤2:卡生成一个8字节的随机数RndB。这个随机数是DES/3 DES与多样化密钥加密,由ek(RndB)表示,然后发送到终端。
步骤3终端在接收到的ek( RndB )上运行DES/3 DES解密操作,从而检索RndB。然后RndB左转8位(第一个字节被移动到RndB的末尾),产生RndB‘。现在终端本身生成一个8字节的随机数RndA。此RndA与RndB‘连接,并使用DES/3 DES加密(这两个块的加密使用密码块链接(CBC)发送模式)。此令牌ek(RndA +RndB‘)被发送到卡。
步骤4:卡在接收到的令牌上运行DES/3 DES解码,从而获得RndA +RndB‘。卡现在可以通过将发送的RndB‘与内部旋转8位的原始RndB’进行比较来验证发送的RndB‘。一个成功的验证证明了卡和终端拥有相同的秘密(密钥)。如果验证失败,卡将停止身份验证过程并返回错误消息。由于该卡还接收到由终端产生的随机数RndA,它可以在RndA上执行8位的旋转左操作以获得RndA‘,这再次被加密,从而产生ek(RndA’)。此令牌被发送到终端。
步骤5:终端在接收到的ek(RndA‘)上运行DES/3 DES解码,从而获得RndA’以便与终端进行比较--内部旋转的RndA‘。如果比较失败,终端将退出该过程并可能停止该卡片。
步骤6:卡将身份验证状态设置为“身份验证”
在此NXP数据表中也可以找到相同的
发布于 2018-05-02 08:51:04
示例C源代码:
typedef unsigned char byte;
int mutual_authentication( const byte *diversifiedKey )
{
byte cmd[256], response[256];
int cmdLen, responseLen;
//Send 1A00
cmd[0] = 0x1A;
cmd[1] = 0x00;
cmdLen = 2;
int ret = send_command( cmd, cmdLen, response, &responseLen );
//Get ekRndB
byte ekRndB[8], rndB[8];
memcpy(ekRndB, response, 8);
//Decrypt ekRndB with diversifiedKey
des_ISO_decrypt( diversifiedKey, ekRndB, rndB, 8 );
//PCD Generates RndA
byte randA[8] = "\x33,\x54,\x2A,\x87,\x21,\x00,\x77,\x98";//random numbers
byte rndARndBComplement[16], ekRndARndBComplement[16];
// Append RndA and RndB' ( RndB' is generated by rotating RndB one byte to the left )
// after the status byte.
memcpy(&rndARndBComplement[0],rndA,8);
memcpy(&rndARndBComplement[8],&rndB[1],7); // bytes 1 to 7
rndARndBComplement[15] = rndB[0]; // byte 0
// Apply the DES send operation to the 16 argument bytes before sending the second frame to the PICC
des_ISO_encrypt(diversifiedKey, rndARndBComplement, ekRndARndBComplement, 16);
cmd[0] = 0xAF;
memcpy(&cmd[1], ekRndARndBComplement, 16);
cmdLen = 17;
ret = send_command( cmd, cmdLen, response, &responseLen );
byte ekRndAComplement[8], rndAComplement[8], finalOutput[8];
memcpy(&ekRndAComplement[0], &response[1], 8);
des_ISO_decrypt(diversifiedKey, ekRndAComplement, rndAComplement, 8);
memcpy(&finalOutput[1], &RndAComplement[0], 7);
finalOutput[0] = rndAComplement[7];
//compare the received RndA with the one we originally had
return memcmp(&finalOutput[0], &rndA[0], 8);
}注意:您应该有自己的send_command() (取决于您的读卡器)、des_ISO_decrypt()和des_ISO_encrypt()的实现(取决于您的DES库)。
https://stackoverflow.com/questions/26815834
复制相似问题