c# - C#中的多线程加密

标签 c# multithreading encryption

我是加密新手,正在使用以下方法加密文件:

private static void encryptFile(string filePath, byte[] password, byte[] salt)
{
    Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(password, salt, 1000);
    AesManaged algorithm = new AesManaged();

    byte[] rgbKey = rdb.GetBytes(algorithm.KeySize / 8);
    byte[] rgbIV = rdb.GetBytes(algorithm.BlockSize / 8);
    GCHandle keyHandle = GCHandle.Alloc(rgbKey, GCHandleType.Pinned);
    GCHandle IVHandle = GCHandle.Alloc(rgbIV, GCHandleType.Pinned);

    ICryptoTransform cryptoAlgorithm = algorithm.CreateEncryptor(rgbKey, rgbIV);

    using (FileStream readStream = File.Open(filePath, FileMode.Open))
    {
        using (FileStream writeStream = new FileStream(filePath + ".enc", FileMode.Create, FileAccess.Write))
        {
            using (CryptoStream cryptoStream = new CryptoStream(writeStream, cryptoAlgorithm, CryptoStreamMode.Write))
            {
                while (readStream.Position < readStream.Length)
                {
                    byte[] buffer = new byte[4096];
                    int amountRead = readStream.Read(buffer, 0, buffer.Length);
                    cryptoStream.Write(buffer, 0, amountRead);
                }
                cryptoStream.Flush();
            }
        }
    }

    UtilityMethods.destroyBytes(rgbKey);
    UtilityMethods.destroyBytes(rgbIV);
    keyHandle.Free();
    IVHandle.Free();
}

我想做的是多线程处理更快的加密。使用单线程,加密一个约 3GB 的文件需要 5 分钟。如果可能的话,我希望能够在 1 分钟内完成该加密(30 秒内会很棒,但我认为我可能会拉伸(stretch))。

我相信答案是创建多个流(虽然我不确定),为每个流分配一个文件 block 来加密,但我不确定如何“分解文件”来分配一个 block 到每个流,或者在每个部分通过分配给它的流之后“将文件放回原处”。有人能指出我正确的方向吗?

非常感谢!

附言我看过这个 ( Rijndael algorithm and CryptoStream: is it possible to encrypt / decrypt multithreaded? ),但我不明白答案(ECB、CBC?)。如果我的问题的答案就在那里,您能否提供一些示例代码让我朝着正确的方向前进?

再次感谢!

最佳答案

CBC(密码 block 链接)是 AesManaged 的​​默认 block 模式。

如果您使用 CBC,则不能使用 AES 并行加密不同的 block ,因为加密 block 1 的副作用是为 block 2 设置新的 IV。这称为“IV 反馈”。如果您并行运行,这将不起作用。您需要选择一个不同的 cipher block mode .

您可以使用 ECB 模式(没有 IV 反馈),但如果您这样做,以明文形式重复的 block 也会以密文形式重复,这使您容易受到某些类型的攻击。

最好是使用 CTR,其中 IV 基于计数器,但是 .NET 似乎不支持它。

我建议您将单个文件分成几个“虚拟”文件,每个文件都有自己的密码流。使用 CBC 并用 RNGCryptoServiceProvider 中的字节填充 IV .使用从物理文件中的虚拟文件索引派生的值为 RNGCryptoServiceProvider 提供种子。这样你就有了一个因 block 而异的 IV,并且重复的明文不会出现在密文中。解密时重复该过程。

另见 this question .

我建议您在 security.stackexchange.com 上发布您的解决方案准备好后进行审核。

关于c# - C#中的多线程加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41734296/

相关文章:

c# - Web 服务返回 xml 尽管返回格式是 json

javascript - 如何在单击按钮时添加特定设计的 html 形式的文本框

c# - 如何在 asp :GridView 中使标题标题居中

C#访问iPhone构建的网页

Java - 使用 ConcurrentLinkedDeque 避免 NonSuchElementException

c# - 在 C# 中重现 Ruby OpenSSL private_encrypt 输出

ruby - 如何使用 Ruby 使用对称 AES256 加密文件并可以使用 gpg 解密?

java - 当 writeLock 锁定时,ReentrantReadWriteLock 是否会读取?

ios - iOS如何等待直到 `didReceiveData`处理程序被调用

c++ - 将 C++ builder 6 项目转换为 C++ builder 2010