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

AES加密解密异常:加密结果多变且无法正常解密求助

问题原因与解决方案

核心问题

你的代码每次调用Aes.Create()时,都会自动生成随机的密钥和初始化向量(IV)。这导致:

  • 同一明文每次加密用的密钥/IV不同,结果自然不一样;
  • 解密时又生成新的随机密钥/IV,和加密时的完全不匹配,所以解密出乱码。

修复AES加密解密代码

如果坚持用AES,需要固定密钥和IV(因为你不需要高强度加密,可以硬编码一套固定值),加密和解密使用同一套密钥/IV:

// 固定的密钥和IV(可自行生成后转为Base64字符串替换占位符)
private static readonly byte[] FixedKey = Convert.FromBase64String("abcdefghijklmnopqrstuvwxyz123456");
private static readonly byte[] FixedIV = Convert.FromBase64String("abcdefghijklmnop");

public static string Encrypt(string plainText)
{
    if (Settings.LicenseOK())
    {
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

        using var symmetricKey = Aes.Create();
        symmetricKey.Key = FixedKey;
        symmetricKey.IV = FixedIV;
        symmetricKey.Padding = PaddingMode.Zeros;

        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(symmetricKey.Key, symmetricKey.IV);
        using MemoryStream ms = new MemoryStream();
        using CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);

        cs.Write(plainTextBytes, 0, plainTextBytes.Length);
        cs.FlushFinalBlock();
        return Convert.ToBase64String(ms.ToArray(), Base64FormattingOptions.None);
    }
    else
        throw new Exception("Errore nella DLL GDWS");
}

public static string Decrypt(string cipherText)
{
    if (Settings.LicenseOK())
    {
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);

        using var symmetricKey = Aes.Create();
        symmetricKey.Key = FixedKey;
        symmetricKey.IV = FixedIV;
        symmetricKey.Padding = PaddingMode.Zeros;

        ICryptoTransform decryptor = symmetricKey.CreateDecryptor(symmetricKey.Key, symmetricKey.IV);
        using MemoryStream ms = new MemoryStream(cipherTextBytes);
        using CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);

        using MemoryStream resultMs = new MemoryStream();
        cs.CopyTo(resultMs);
        byte[] plainTextBytes = resultMs.ToArray();
        // 移除填充的0字节避免乱码
        plainTextBytes = plainTextBytes.TakeWhile(b => b != 0).ToArray();
        return Encoding.UTF8.GetString(plainTextBytes);
    }
    else
        throw new Exception("Errore nella DLL GDWS");
}

说明:

  • 固定密钥/IV可通过临时调用一次Aes.Create(),提取其Key和IV转成Base64字符串得到;
  • 修复了解密时的读取逻辑,改用CopyTo确保读取完整数据,同时移除填充的0字节避免末尾乱码。

更适合需求的方案:仅防篡改(无需加密内容)

如果你不需要隐藏明文内容,只是防止用户篡改,用HMAC签名更简单高效:把明文和签名拼接存储,读取时重新计算签名对比即可。

private static readonly byte[] HmacKey = Convert.FromBase64String("abcdefghijklmnopqrstuvwxyz123456");

// 生成带签名的字符串
public static string CreateSignedString(string plainText)
{
    if (!Settings.LicenseOK())
        throw new Exception("Errore nella DLL GDWS");

    using var hmac = new HMACSHA256(HmacKey);
    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
    byte[] signatureBytes = hmac.ComputeHash(plainBytes);
    string signature = Convert.ToBase64String(signatureBytes);
    return $"{plainText}||{signature}";
}

// 验证并提取原始明文
public static string VerifyAndGetOriginal(string signedText)
{
    if (!Settings.LicenseOK())
        throw new Exception("Errore nella DLL GDWS");

    string[] parts = signedText.Split(new[] { "||" }, StringSplitOptions.None);
    if (parts.Length != 2)
        throw new InvalidOperationException("字符串已被篡改");

    string plainText = parts[0];
    string storedSignature = parts[1];

    using var hmac = new HMACSHA256(HmacKey);
    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
    byte[] computedSignatureBytes = hmac.ComputeHash(plainBytes);
    string computedSignature = Convert.ToBase64String(computedSignatureBytes);

    // 常量时间比较防止时序攻击
    if (!CryptographicOperations.FixedTimeEquals(Encoding.UTF8.GetBytes(storedSignature), Encoding.UTF8.GetBytes(computedSignature)))
        throw new InvalidOperationException("字符串已被篡改");

    return plainText;
}

优势:

  • 逻辑简单,无需处理加密解密的填充、IV等细节;
  • 明文可见,但用户篡改后签名会不匹配,无法通过验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:15:36