解密AES十六进制报文完成服务器双向认证问题求助
解决CryptoJS AES-CBC解密空输出问题并完成认证流程
我来帮你排查问题并完成整个认证流程的代码,你的代码有几个关键问题导致了解密失败输出空字符串,我们一步步来修正:
问题分析
你的代码主要有三个核心错误:
- 密文和密钥格式错误:CryptoJS的
AES.decrypt默认接受Base64编码的密文或CipherParams对象,而你直接传入了十六进制字符串;同时密钥直接传字符串会让CryptoJS把它当成密码,用PBKDF2派生密钥,而不是直接使用你提供的十六进制字节作为AES密钥。 - 缺少IV参数:AES-CBC模式必须指定初始化向量(IV),你没有配置导致解密模式不匹配。
- 未指定填充方式:你的数据都是16字节(正好是AES128的块大小),不需要填充,默认的PKCS7填充会导致解密失败。
修正后的完整代码
下面是符合你需求的完整实现,包含从解密变量A、拼接、到最终解密生成服务器所需值的全流程:
// 你的原始变量(十六进制字符串) const hexA = 'e06e3e2ea024bba1185c33d64d2033b6'; const hexKey = '41435231323535552d4a312041757468'; // 1. 将十六进制字符串转换为CryptoJS可识别的WordArray const ciphertextA = CryptoJS.enc.Hex.parse(hexA); const key = CryptoJS.enc.Hex.parse(hexKey); // 2. 配置AES-CBC参数:IV这里假设为全0(如果你的场景IV不同,请替换为对应十六进制) const iv = CryptoJS.enc.Hex.parse('00000000000000000000000000000000'); const aesConfig = { mode: CryptoJS.mode.CBC, iv: iv, padding: CryptoJS.pad.NoPadding // 16字节块无需填充 }; // 3. 解密变量A得到原始16字节随机数R const decryptedR = CryptoJS.AES.decrypt( { ciphertext: ciphertextA }, // 传递CipherParams对象 key, aesConfig ); const hexR = decryptedR.toString(CryptoJS.enc.Hex); console.log('解密得到的随机数R:', hexR); // 4. 拼接变量A和R,生成32字节的十六进制字符串 const hexS = hexA + hexR; console.log('拼接后的32字节数据:', hexS); // 5. 解密32字节数据,得到最终发送给服务器的值 const ciphertextS = CryptoJS.enc.Hex.parse(hexS); const finalDecrypted = CryptoJS.AES.decrypt( { ciphertext: ciphertextS }, key, aesConfig ); const finalHexResult = finalDecrypted.toString(CryptoJS.enc.Hex); console.log('最终发送给服务器的32字节十六进制值:', finalHexResult);
关键说明
- IV的确认:如果你的场景中加密随机数R时使用的不是全0IV,请替换
iv变量为对应的十六进制字符串(必须是16字节)。 - 填充方式:因为所有数据都是刚好的AES块大小(16字节),所以必须使用
NoPadding,否则会出现解密错误。 - 数据格式转换:所有十六进制字符串必须先通过
CryptoJS.enc.Hex.parse()转换为WordArray,才能被CryptoJS正确处理。
内容的提问来源于stack exchange,提问作者jskidd3
相关产品推荐
相关产品推荐

