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

如何将本地AES加密文件解密为FileStream?

问题翻译

我本地存储着用AES加密的文件,需要在代码中将其中一个文档以解密后的Stream形式获取,但尝试多次均未成功。请问DecryptFile方法应如何实现,才能返回包含解密内容的Stream?我的加密方法如下:

public async Task EncryptAndSaveFileAsync(Stream stream, string filePath)
{
    await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write);

    var tempFilePath = Path.GetTempFileName();

    try
    {
        if (!stream.CanRead)
        {
            stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        }

        await using (var tempFileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write))
        {
            await stream.CopyToAsync(tempFileStream);
        }

        fileStream.Close();

        try
        {
            await using var inputFileStream = new FileStream(tempFilePath, FileMode.Open, FileAccess.Read);

            await using (var outputFileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                using var aesAlg = Aes.Create();
                aesAlg.Key = _key;
                aesAlg.IV = new byte[16];

                await using var cryptoStream = new CryptoStream(outputFileStream, aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV), CryptoStreamMode.Write);
                await inputFileStream.CopyToAsync(cryptoStream);
            }

            inputFileStream.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Fehler beim Verschlüsseln der Datei: " + ex.Message);
        }
    }
    catch (Exception ex)
    {
        // TODO FM Logging
    }
    finally
    {
        File.Delete(tempFilePath);
    }
}

解密方法实现

要实现返回解密后Stream的方法,必须和加密逻辑严格对齐:使用相同的AES密钥、初始化向量(IV),并选择正确的CryptoStream模式。以下是具体实现:

public async Task<Stream> DecryptFileAsync(string encryptedFilePath)
{
    // 用内存流存储解密后的内容,最终返回该流
    var decryptedStream = new MemoryStream();

    await using var encryptedFileStream = new FileStream(encryptedFilePath, FileMode.Open, FileAccess.Read);
    using var aesAlg = Aes.Create();
    aesAlg.Key = _key; // 和加密时使用的密钥完全一致
    aesAlg.IV = new byte[16]; // 和加密时的IV保持相同(全0的16字节数组)

    // 创建解密用的CryptoStream,模式为Read(读取加密流并解密)
    await using var cryptoStream = new CryptoStream(encryptedFileStream, aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV), CryptoStreamMode.Read);
    
    // 将解密后的内容复制到内存流
    await cryptoStream.CopyToAsync(decryptedStream);
    
    // 重置内存流指针到起始位置,确保调用方能正常读取
    decryptedStream.Position = 0;

    return decryptedStream;
}

核心注意事项

  • 密钥与IV一致性:解密时必须使用和加密时完全相同的Key和IV,你的加密代码中IV固定为new byte[16](全0),解密时不能修改这个值。
  • CryptoStream模式:加密用CryptoStreamMode.Write(写入时加密),解密必须用CryptoStreamMode.Read(读取时解密),模式错误会直接导致解密失败。
  • 流位置重置:返回内存流前必须将Position设为0,否则调用方读取时会从流的末尾开始,无法获取有效内容。

加密代码优化提示(可选)

你的加密代码存在冗余操作:

  • 开头创建的fileStream被直接Close,无实际作用,可删除。
  • 无需先将输入流复制到临时文件再加密,直接对原始输入流加密写入目标文件即可,减少IO开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 01:48:30