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

AES解密偶现异常:Gzip解压失败问题排查与解决

偶现Gzip解压异常的AES解密问题处理

问题描述

实现了特定事件触发的解密功能,但偶尔会抛出无法解释的异常。

处理流程

  • 获取主密钥/IV
  • Base64解码
  • AES-256 CBC解密
  • Gzip解压(偶现失败环节)
  • UTF-8解码

相关代码

public async Task<byte[]> PrivateDecrypt(long userId, byte[] data)
{
   var key = await this.GetOrAddPrivateEncryptionKey(userId);
   var keyBytes = key.ToUTF8Bytes();
   var (cipher, ivBytes) = data.ExtractIVPadding();

   var decrypted = await cipher
      .AESDecryptAndDecompressAsync(keyBytes, ivBytes)
      .ConfigureAwait(false);

   return decrypted;
}
public static byte[] FromBase64(this string base64) => Convert.FromBase64String(base64);
public static async Task<byte[]> AESDecryptAndDecompressAsync(this byte[] cipher, byte[] key, byte[] iv)
{
   if (cipher == null || cipher.Length <= 0)
      throw new ArgumentNullException(nameof(cipher), "incorrect data");

   if (key == null || key.Length != 32)
      throw new ArgumentNullException(nameof(key), "incorrect key");

   if (iv == null || iv.Length != 16)
      throw new ArgumentNullException(nameof(iv), "incorrect iv");

   using var aesAlg = Aes.Create();

   aesAlg.Mode = CipherMode.CBC;
   aesAlg.KeySize = 256;

   aesAlg.Key = key;
   aesAlg.IV = iv;
   aesAlg.Padding = PaddingMode.PKCS7;

   using var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

   using (var decompressedStream = new MemoryStream())
   {
      using (var encryptedStream = new MemoryStream(cipher))
      {
         using (var cryptoStream = new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read))
         {
            using (var gzipStream = new GZipStream(cryptoStream, CompressionMode.Decompress))
               await gzipStream.CopyToAsync(decompressedStream).ConfigureAwait(false);

            return decompressedStream.ToArray();
         }           
      }           
   }
}

异常堆栈信息

System.IO.InvalidDataException: The archive entry was compressed using an unsupported compression method.
   at System.IO.Compression.Inflater.Inflate(FlushCode flushCode)
   at System.IO.Compression.Inflater.ReadInflateOutput(Byte* bufPtr, Int32 length, FlushCode flushCode, Int32& bytesRead)
   at System.IO.Compression.Inflater.InflateVerified(Byte* bufPtr, Int32 length)
   at System.IO.Compression.DeflateStream.CopyToStream.WriteAsyncCore(ReadOnlyMemory`1 buffer, CancellationToken cancellationToken)
   at System.Security.Cryptography.CryptoStream.CopyToAsyncInternal(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
   at System.IO.Compression.DeflateStream.CopyToStream.CopyFromSourceToDestinationAsync()
   at Trading.Tools.Bytes.EncryptionExtensions.AESDecryptAndDecompressAsync(Byte[] cipher, Byte[] key, Byte[] iv) in /src/Trading.Tools/Bytes/EncryptionExtensions.cs:line 207
   at Trading.Web.Commons.Encryption.LocalEncryptionService.PrivateDecrypt(Int64 userId, Byte[] data) in /src/Trading.Web.Commons/Encryption/LocalEncryptionService.cs:line 107

从堆栈信息可见,问题出在解密后的Gzip解压环节。

假设

  • 代码逻辑本身是可行的
  • 异常出现频率极低
  • 数据库中数据是正确的,否则功能完全无法运行

分析思路

由于问题具有随机性,推测是竞态条件导致,可能的原因:

  • 数据库未返回完整字符串,误转义字符,但无法解释解密为何能成功
  • 解密偶尔返回异常结果,怀疑存在共享状态问题

环境信息

  • 使用EFCore 8.0.2读取数据库
  • .NET Core 8.0.3环境
  • PostgreSQL 16.1-bullseye数据库

更新记录

  • 按@Charlieface建议修改代码后,问题仍存在
  • 替换加密逻辑为BouncyCastle Nuget包后,问题解决。升级至8.0.3前无此问题,疑为版本补丁导致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 10:15:27