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

使用CryptoStream解密返回空文件问题排查

解密后文件为空的问题排查与解决

我帮你找出解密后文件为空的核心原因了——加密阶段的FileStream位置没有重置到开头,导致你实际加密的是空内容,解密自然也只能得到空文件。下面一步步分析问题并给出修正方案:

问题根源分析

在你的tempEncrypt方法中,创建test.txt并写入"Test String"后,FileStream的指针已经移动到了文件末尾。此时直接把这个流传给Encrypt方法调用source.CopyTo(cryptoStream),因为流的位置在末尾,没有任何数据可以复制,最终加密的encrypted.tmp是空文件,替换原文件后,解密当然只能得到空内容。

另外还有两个小细节会影响加密解密的正确性:

  1. 加密时没有调用CryptoStream.FlushFinalBlock(),AES是块加密算法,最后一块数据需要填充,这个方法会确保所有加密数据都写入目标流。
  2. 手动调用Stream.Close()容易导致资源泄漏,应该用using语句自动管理流的生命周期。

修正后的代码

加密部分代码调整

tempEncrypt方法

重新打开文件流(确保指针在开头),或者写入后重置流位置:

private void tempEncrypt() { 
    // Creates file with "Test String" inside
    byte[] test = Encoding.ASCII.GetBytes("Test String");
    using (var file = File.Create("test.txt"))
    {
        file.Write(test, 0, test.Length);
    }

    // 重新打开文件流,此时指针默认在文件开头
    using (var file = File.OpenRead("test.txt"))
    {
        // Saves key and IV for decryption
        var temp = new AesCryptoServiceProvider();
        Console.WriteLine(System.Convert.ToBase64String(temp.Key));
        Console.WriteLine(System.Convert.ToBase64String(temp.IV));
        Encryptor.Encrypt(file, temp.Key, temp.IV);
    }
}

Encrypt方法

用using管理所有流资源,添加FlushFinalBlock()确保加密数据完整写入:

public static void Encrypt(FileStream source, byte[] key, byte[] IV) { 
    string path = source.Name;
    
    // 用using自动管理目标流资源
    using (var destination = File.Create("encrypted.tmp"))
    using (var provider = new AesCryptoServiceProvider())
    using (var transform = provider.CreateEncryptor(key, IV))
    using (var cryptoStream = new CryptoStream(destination, transform, CryptoStreamMode.Write)) {
        // 双重保险:确保源流指针在开头
        source.Seek(0, SeekOrigin.Begin);
        // 复制数据进行加密
        source.CopyTo(cryptoStream);
        // 确保所有加密数据(包括最后一块填充数据)写入目标流
        cryptoStream.FlushFinalBlock();
    }

    // 替换原文件
    File.Delete(path);
    File.Move("encrypted.tmp", path);
}

解密部分代码调整

Decrypt方法

同样用using管理流资源,确保源流指针在开头:

public static void Decrypt(FileStream source, byte[] key, byte[] IV) { 
    string path = source.Name;
    
    using (var destination = File.Create("decrypted.tmp"))
    using (var provider = new AesCryptoServiceProvider())
    using (var transform = provider.CreateDecryptor(key, IV))
    using (var cryptoStream = new CryptoStream(source, transform, CryptoStreamMode.Read)) {
        // 确保源流指针在开头
        source.Seek(0, SeekOrigin.Begin);
        // 解密并写入目标文件
        cryptoStream.CopyTo(destination);
    }

    // 替换原文件
    source.Close();
    File.Delete(path);
    File.Move("decrypted.tmp", path);
}

额外注意事项

  • 保存的Key和IV必须完全匹配,解密时不能写错,否则会解密失败或得到乱码。
  • AesCryptoServiceProvider在.NET Core/.NET 5+中已被标记为过时,建议改用Aes.Create()来创建AES实例,兼容性更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 17:12:32