C# AES加密结果经原有解密函数解密出现乱码问题求助
核心问题
你两次写的加密函数都没有匹配原解密函数的输入规则,具体错误如下:
- 字节结构不匹配:原解密函数对base64解码后的字节数组有固定结构要求:
- 前16字节:AES解密用的IV
- 16~47位共32字节:原代码中仅读取但未实际使用,仅作为占位段
- 48字节之后:真实的AES密文
你两次加密都没有按这个结构拼接输出字节,第一次缺了IV和占位段,第二次错误写入了两次Key导致解密前缀出现乱码。
- 编码不匹配:原解密用
Encoding.ASCII将解密后的字节转明文,你第一次加密用了UTF8编码,还使用了StreamWriter写入明文,会引入额外的编码头导致解密错误。 - IV使用错误:第一次加密用了固定全0的IV,且没有将IV写入输出字节的前16位,导致解密初始向量不匹配出现前缀乱码。
修复方案
严格按照原解密的结构生成加密后的字节数组:
- 随机生成16位合法IV(AES-CBC模式要求IV长度为16字节)
- 将明文转ASCII编码的字节数组
- 使用
GetToken()作为Key,生成的随机IV作为IV,加密明文字节得到密文 - 按顺序拼接三个段:IV(16字节) + 任意32字节占位段 + 密文
- 将拼接后的完整字节数组转base64字符串即可
修复后代码
public void EncryptStringToBytes() { string plainText = textBox2.Text.Trim(); // 明文转ASCII编码,和原解密保持一致 byte[] plainBytes = Encoding.ASCII.GetBytes(plainText); byte[] encryptedData; using (Aes aesAlg = Aes.Create()) { aesAlg.Key = GetToken(); // 生成随机16位IV aesAlg.GenerateIV(); byte[] iv = aesAlg.IV; aesAlg.Mode = CipherMode.CBC; // 显式指定填充模式,和默认值保持一致避免环境差异 aesAlg.Padding = PaddingMode.PKCS7; ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, iv); using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { // 直接写入明文字节,不要用StreamWriter避免编码问题 csEncrypt.Write(plainBytes, 0, plainBytes.Length); csEncrypt.FlushFinalBlock(); encryptedData = msEncrypt.ToArray(); } } // 拼接最终输出字节:16位IV + 32位占位符 + 密文 byte[] finalBytes = new byte[16 + 32 + encryptedData.Length]; // 写入前16位IV Buffer.BlockCopy(iv, 0, finalBytes, 0, 16); // 中间32位随便填,这里用全0即可,解密不会用到 Buffer.BlockCopy(new byte[32], 0, finalBytes, 16, 32); // 写入48位之后的密文 Buffer.BlockCopy(encryptedData, 0, finalBytes, 48, encryptedData.Length); // 转base64输出 textBox3.Text = Convert.ToBase64String(finalBytes); } }
内容的提问来源于stack exchange,提问作者kokosik 1221
相关产品推荐
相关产品推荐

