1 回答

TA贡献1772条经验 获得超5个赞
cypherText
如果明文的大小(顺便说一下,这是一个误导性术语)不是块大小(AES 为 16 字节)的整数倍,则Go 代码会填充 0x30 值。使用密码 ( ) 的 SHA256 值的前 16 个字节的十六进制编码的 UTF-8 编码作为密钥word
。密文是十六进制编码的。
在线工具解密失败,因为在线工具使用PKCS#7 padding,密文是Base64解码的。为了能够解密,必须禁用默认的 PKCS#7 填充并且必须对密文进行十六进制解码,请参见CyberChef。
使用 JavaScript 代码解密失败,因为 CryptoJS 默认使用 PKCS#7 填充,密钥被十六进制解码,并且密文未作为CipherParams
对象传递。为了能够解密,必须禁用默认的 PKCS#7 填充,密钥必须采用 UTF-8 编码,并且密文必须作为CipherParams
对象传递:
var password = 'день';
var key = CryptoJS.SHA256(password).toString();
key = key.substring(0, key.length/2);
var ciphertext = '46ef70c1193fa29024595964a0eb0157c4e6602da6c1429f8a2b81146f79e798'
var decrypted = CryptoJS.AES.decrypt(
{ciphertext: CryptoJS.enc.Hex.parse(ciphertext)}, // Fix 1: pass a CipherParams object
CryptoJS.enc.Utf8.parse(key), // Fix2: UTF-8 encode the key
{ mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); // Fix 3: disable padding
console.log(decrypted.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
给出解密后的 UTF-8 解码数据:деньBvFGlrXeWCnPTwFC00000000
。
安全性:ECB 不使用 IV,因此不安全。如今,应用了经过身份验证的加密(例如 GCM),但至少是一种带有 IV 的模式(例如 CBC)。
此外,使用摘要作为密钥派生函数 (KDF) 是不安全的。为此有专门的功能(例如 Argon2 或 PBKDF2)。另外,应该直接使用KDF的字节串,而不是hex编码的UTF-8编码,这样会降低安全性。
应用的 0x30 填充通常是不可靠的。更可靠的是例如 PKCS#7 填充。
- 1 回答
- 0 关注
- 415 浏览
添加回答
举报