使用CryptoJS AES加密、C# AES解密时出现IV块大小不匹配错误
问题解决:AES解密时IV与块大小不匹配的错误
核心问题分析
- AES算法块大小固定为16字节(128位),你的C#代码中IV是32字节,不符合算法要求
- 加密端采用CBC模式,C#代码却误用ECB模式,加密模式不匹配
- 密文处理逻辑错误:CryptoJS加密输出的是Base64格式,你用UTF8转字节数组会导致数据损坏
错误根源细节
CryptoJS里CryptoJS.MD5()返回的是16字节的二进制哈希值,但你在C#中把该哈希对应的十六进制字符串用Encoding.UTF8.GetBytes()转换——十六进制字符串每个字符占1字节,16字节哈希转成十六进制是32个字符,最终得到32字节的IV,自然和AES要求的16字节块大小不匹配。
修正后的C#代码
byte[] iv = StringToByteArray(hexIv); // 将十六进制字符串转为16字节数组 byte[] key = StringToByteArray(hexKey); byte[] cipher = Convert.FromBase64String(sCipher); // 密文是Base64格式,用Base64解析 using (Aes aes = Aes.Create()) { aes.Key = key; aes.IV = iv; aes.Mode = CipherMode.CBC; // 和加密端保持一致使用CBC模式 aes.Padding = PaddingMode.PKCS7; ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); using (MemoryStream msDecrypt = new MemoryStream(cipher)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { decrypted = srDecrypt.ReadToEnd(); } } } } // 辅助方法:十六进制字符串转字节数组 private static byte[] StringToByteArray(string hex) { int length = hex.Length; byte[] bytes = new byte[length / 2]; for (int i = 0; i < length; i += 2) { bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); } return bytes; }
关键修正点
- 替换IV和Key的转换方式:用十六进制转字节数组的方法,将32位十六进制字符串转为16字节二进制数组,匹配AES块大小要求
- 将加密模式从ECB改为CBC,与CryptoJS端保持一致
- 密文改用
Convert.FromBase64String解析,因为CryptoJS的encrypt().toString()输出的是Base64编码的密文
内容的提问来源于stack exchange,提问作者Douglas Fernandes
相关产品推荐
相关产品推荐

