You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# AES解密希伯来字母显示为问号问题求助

解决希伯来字母加密解密后显示为问号的问题

这个问题的核心原因非常明确:你使用的ASCIIEncoding根本不支持希伯来字母这类非ASCII字符!ASCII编码仅覆盖0-127的基础字符,任何超出这个范围的字符(包括希伯来语、中文、阿拉伯语等)都会被直接替换成问号?,所以从加密前的字节转换阶段就已经丢失了原始字符信息,解密自然只能得到一堆问号。

下面是具体的修复方案和优化后的代码:

1. 替换编码为UTF-8(或Unicode)

UTF-8是通用的Unicode字符编码,完美支持希伯来字母,而且兼容性好。你需要把所有ASCIIEncoding替换为UTF8Encoding,并且加密和解密必须使用完全相同的编码。

2. 完善AES加密的必要配置

你的原始代码缺少了AES加密的关键参数:初始化向量(IV)、加密模式和填充模式。这些参数在加密和解密时必须完全一致,否则解密会失败或乱码。另外,IV应该是随机生成的(不要硬编码),每次加密生成新的IV,然后和密文一起存储/传输。

优化后的完整代码示例

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class AesEncryptionHelper
{
    // 注意:密钥需要是256位(32字节),这里只是示例,请使用安全的密钥管理方式
    private static readonly byte[] _key = Encoding.UTF8.GetBytes("Your32ByteLongSecureKeyHere123");

    public static string Encrypt(string plainText)
    {
        if (string.IsNullOrEmpty(plainText))
            throw new ArgumentNullException(nameof(plainText));

        using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
        {
            aes.BlockSize = 128;
            aes.KeySize = 256;
            aes.Key = _key;
            aes.Mode = CipherMode.CBC; // 推荐使用CBC模式
            aes.Padding = PaddingMode.PKCS7; // 标准填充模式

            // 生成随机IV
            aes.GenerateIV();
            byte[] iv = aes.IV;

            // 创建加密器
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, iv);

            // 转换明文为UTF-8字节
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

            // 执行加密
            byte[] cipherTextBytes;
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                {
                    cs.Write(plainTextBytes, 0, plainTextBytes.Length);
                    cs.FlushFinalBlock();
                    cipherTextBytes = ms.ToArray();
                }
            }

            // 将IV和密文拼接(IV在前,方便解密时拆分),然后转为Base64字符串返回
            byte[] combinedBytes = new byte[iv.Length + cipherTextBytes.Length];
            Buffer.BlockCopy(iv, 0, combinedBytes, 0, iv.Length);
            Buffer.BlockCopy(cipherTextBytes, 0, combinedBytes, iv.Length, cipherTextBytes.Length);
            return Convert.ToBase64String(combinedBytes);
        }
    }

    public static string Decrypt(string encryptedText)
    {
        if (string.IsNullOrEmpty(encryptedText))
            throw new ArgumentNullException(nameof(encryptedText));

        // 从Base64字符串还原字节数组
        byte[] combinedBytes = Convert.FromBase64String(encryptedText);

        using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
        {
            aes.BlockSize = 128;
            aes.KeySize = 256;
            aes.Key = _key;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;

            // 拆分IV和密文(IV长度是16字节,因为BlockSize是128位=16字节)
            byte[] iv = new byte[16];
            byte[] cipherTextBytes = new byte[combinedBytes.Length - iv.Length];
            Buffer.BlockCopy(combinedBytes, 0, iv, 0, iv.Length);
            Buffer.BlockCopy(combinedBytes, iv.Length, cipherTextBytes, 0, cipherTextBytes.Length);

            aes.IV = iv;

            // 创建解密器
            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

            // 执行解密
            byte[] plainTextBytes;
            using (MemoryStream ms = new MemoryStream(cipherTextBytes))
            {
                using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                {
                    using (MemoryStream outputMs = new MemoryStream())
                    {
                        cs.CopyTo(outputMs);
                        plainTextBytes = outputMs.ToArray();
                    }
                }
            }

            // 用UTF-8还原字符串,支持希伯来字母
            return Encoding.UTF8.GetString(plainTextBytes);
        }
    }
}

额外注意事项

  • 密钥管理:绝对不要硬编码密钥,建议使用安全的密钥存储方案(比如Windows的DPAPI、Azure Key Vault等)。
  • IV的重要性:IV必须是随机且唯一的,但不需要保密,可以和密文一起公开传输/存储。
  • 资源释放:使用using语句自动释放AesCryptoServiceProvider和流对象,避免资源泄漏。

内容的提问来源于stack exchange,提问作者riv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:02:56