C#解密Java传递的AES加密内容时遇“输入字符串非完整块”错误
解决C#解密Java AES加密内容时的“输入字符串不是完整块”错误
问题原因分析
对比Java与C#代码,报错的核心问题有三点:
- Salt值不匹配:Java端使用的salt是
"vdKnilESoIqCGc",但C#代码误用了"220120221623321",导致生成的密钥不一致,解密时无法正确解析块数据。 - 加密字符串预处理缺失:Java解密前会对加密字符串做URL解码(
getUrlDecoder().decode),而C#直接将加密字符串转成UTF-8字节数组,跳过了URL解码和Base64解码步骤,输入的字节流并非合法的AES加密块。 - Base64格式不兼容:Java端的加密字符串是URL安全Base64(用
_替代/、-替代+),C#默认的Convert.FromBase64String不支持该格式,需先转换为标准Base64。
修复后的C#代码
byte[] iv1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int keySize = 256; // 修正为Java端一致的salt string salt = "vdKnilESoIqCGc"; string passphrase = "vdKnilESoIqCGc"; string ecres = "bDs_GiEdNL_2U-JVvSFKi0EBN7xdBlpR2V27lFUniHdY_O23gs57169BUbk8rA3vBo7USX1kzAE510ezkHeuTALMDlKXxa_eywYIXg-Ih8Stk4RIVP6HdKgkAXOoRRx3LZXruyBNo0kFPmVNlDREscqvwmjXLRsjLCbUfZepXI9oiREDfRKjZVQ5sACr8SvZuVatdHFBXUd84FCtbxUBNgstAT2yDCw1E_9BdECaTWiww6Fem4ISCEOOzg8h5nvG4GIWG_67ogWIgXiqHroNdV0gTZRppNlEE2M1W15rfWE="; // 1. URL解码加密字符串 string urlDecrypted = System.Net.WebUtility.UrlDecode(ecres); // 2. 将URL安全Base64转换为标准Base64格式 string standardBase64 = urlDecrypted.Replace('_', '/').Replace('-', '+'); // 3. Base64解码得到加密字节数组 byte[] buffer = Convert.FromBase64String(standardBase64); // 生成与Java端一致的密钥 using (var rfcdb = new System.Security.Cryptography.Rfc2898DeriveBytes( passphrase, System.Text.Encoding.UTF8.GetBytes(salt), 65536, System.Security.Cryptography.HashAlgorithmName.SHA256)) { byte[] key = rfcdb.GetBytes(32); using (var aes = new System.Security.Cryptography.AesCryptoServiceProvider()) { aes.KeySize = keySize; aes.BlockSize = 128; aes.Mode = System.Security.Cryptography.CipherMode.CBC; // AES块大小128位时,PKCS5Padding与PKCS7Padding等价 aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7; aes.IV = iv1; aes.Key = key; using (var decrypt = aes.CreateDecryptor(aes.Key, aes.IV)) { byte[] decryptedText = decrypt.TransformFinalBlock(buffer, 0, buffer.Length); // 统一用UTF-8转字符串,避免平台编码差异 string result = System.Text.Encoding.UTF8.GetString(decryptedText); Console.WriteLine(result); } } }
额外说明
- Java的
PKCS5Padding和C#的PKCS7Padding在AES(128位块大小)场景下完全兼容,无需调整。 - 所有字符串转字节数组的操作统一使用UTF-8编码,避免因平台默认编码差异导致的密钥或数据不一致。
内容的提问来源于stack exchange,提问作者Shashank
相关产品推荐
相关产品推荐

