为了与 ACR1255U-J1 NFC 阅读器进行通信,需要进行身份验证。使用十六进制字符串通过蓝牙连接。
这是我的两种加密和解密方法:
encrypt(valueStringHex, keyStringHex) {
const CryptoJS = require('crypto-js');
const value = CryptoJS.enc.Hex.parse(valueStringHex);
const key = CryptoJS.enc.Hex.parse(keyStringHex);
const encryptedStringHex = CryptoJS.AES.encrypt(value, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.ZeroPadding}).ciphertext.toString();
return encryptedStringHex;
}
decrypt(valueStringHex, keyStringHex) {
const CryptoJS = require('crypto-js');
const value = CryptoJS.enc.Hex.parse(valueStringHex);
const key = CryptoJS.enc.Hex.parse(keyStringHex);
const decryptedStringHex = CryptoJS.AES.decrypt({ciphertext: value}, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding});
return decryptedStringHex.toString();
}
阅读器附带了一个演示应用程序,我在该应用程序中记录了身份验证期间的蓝牙流量。我用 Wireshark 检查了这个。基于在 Wireshark 中看到的通信,我试图证明我在我的应用程序中对身份验证过程的编码。
ACR1255 文档说:
在第 1 步:我从 ACR 阅读器接收到使用客户主密钥加密的 16 字节随机数序列。我应该使用正确的客户主密钥(41435231323535552d4a312041757468)对其进行解密。
根据 Wireshark,这是我在第一步从 ACR1255 阅读器(关键部分以粗体显示)收到的信息:83001500000021E100004500 5ff58680541c5a5903f4833dfaa428bf 1c0a
decrypt('5ff58680541c5a5903f4833dfaa428bf', '41435231323535552d4a312041757468')
=> Result is 6064a82b7edf62986b0a2ec79e922aad
在第 2 步:根据文档,我必须发送以下内容。
abAuthData[0:15] – 我生成的 16 个字节的随机数
abAuthData[16:31] – 从 ACR1255U-J1 收到的 16 个字节的解密随机数(这将是第一步 6064a82b7edf62986b0a2ec79e922aad 的结果,我猜)
总体 32 -byte 随机数将使用客户主密钥解密并返回给 ACR1255U-J1 读卡器。
根据 Wireshark,这是演示应用程序现在发送给 ACR1255 阅读器的内容(关键部分以粗体显示):
6B0025000000EAE000004600 7088e66af57bf04e66a8b2e83614f288 c8ed5005b914b51e50285a93408e1492 2c0a
当然,这是已经解密的密钥。为了证明我对工作流程的理解,我对其进行了加密,并希望将步骤 1 的结果作为密钥的第二部分。但事实并非如此。
encrypt('7088e66af57bf04e66a8b2e83614f288c8ed5005b914b51e50285a93408e1492', '41435231323535552d4a312041757468')
=> Result is 493aa0c5476f551d3b2bce664cfe4305*3b61bce6e4c0837be30453ddad165180*
我对文档中描述的工作流程有什么误解?是否能够以与文档不同的方式描述它?
文档也可以在这里找到。第 32 至 35 页。
附言。我知道,文档说 AES CBC 模式。但是没有使用 IV,据我所知,ECB 模式的用法是一样的。