C# Zip然后将多个文件加密到单个存档中

C# Zip然后将多个文件加密到单个存档中,c#,encryption,zip,compression,aes,C#,Encryption,Zip,Compression,Aes,根据标题,我想采取多个文件,压缩和加密他们使用AES256在一个单一的存档在一次通过这可能吗? 我已成功地使用以下代码将单个文件保存到单个存档中: internal static void Encrypt(string filePath, string zipPath, byte[] key) { // Create the streams used for encryption. using (var outputStream = new FileStream(zipPath,

根据标题,我想采取多个文件,压缩和加密他们使用AES256在一个单一的存档在一次通过这可能吗?

我已成功地使用以下代码将单个文件保存到单个存档中:

internal static void Encrypt(string filePath, string zipPath, byte[] key)
{
    // Create the streams used for encryption.
    using (var outputStream = new FileStream(zipPath, FileMode.Create, FileAccess.Write))
    {
        using (var aes = Aes.Create())
        {
            aes.BlockSize = 128;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;
            aes.KeySize = 256;

            aes.Key = key;
            aes.GenerateIV();

            // Write the IV in to the start of the file first.
            outputStream.Write(aes.IV, 0, aes.IV.Length);

            using (ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
            using (CryptoStream csEncrypt = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
            {
                using (DeflateStream zip = new DeflateStream(csEncrypt, CompressionMode.Compress, true))
                {
                    byte[] buffer = new byte[8192];

                    using (var dataStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                    {
                        int bytesRead = dataStream.Read(buffer, 0, buffer.Length);

                        // Read the data in to a buffer to limit memory usage.
                        while (bytesRead > 0)
                        {
                            zip.Write(buffer, 0, bytesRead);

                            bytesRead = dataStream.Read(buffer, 0, buffer.Length);
                        }
                    }
                }

                //Flush after DeflateStream is disposed.
                csEncrypt.FlushFinalBlock();
            }
        }
    }
}
然后,我尝试通过使用
ZipArchive
进一步实现这一点,以使用以下内容包含多个文件:

internal static void EncryptArchive(string filePath, string zipPath, byte[] key)
{
    // Create the streams used for encryption.
    using (var outputStream = new FileStream(zipPath, FileMode.Create, FileAccess.Write))
    {
        using (var aes = Aes.Create())
        {
            aes.BlockSize = 128;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;
            aes.KeySize = 256;

            aes.Key = key;
            aes.GenerateIV();

            // Write the IV in to the start of the file first.
            outputStream.Write(aes.IV, 0, aes.IV.Length);

            using (ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
            using (CryptoStream csEncrypt = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
            {
                using (var zip = new ZipArchive(csEncrypt, ZipArchiveMode.Create, false))
                {
                    byte[] buffer = new byte[8192];

                    var entry = zip.CreateEntry(Path.GetFileName(filePath));

                    using (var dataStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                    using (var entryStream = entry.Open())
                    {
                        int bytesRead = dataStream.Read(buffer, 0, buffer.Length);

                        // Read the data in to a buffer to limit memory usage.
                        while (bytesRead > 0)
                        {
                            entryStream.Write(buffer, 0, bytesRead);

                            bytesRead = dataStream.Read(buffer, 0, buffer.Length);
                        }
                    }
                }

                //Flush after DeflateStream is disposed.
                csEncrypt.FlushFinalBlock();
            }
        }
    }
}
现在,虽然该方法未设置为处理多个文件,但它目前甚至无法处理1个文件。当我试图写入entryStream时,就会抛出一个异常,指出该流不支持
CanSeek

我假设ZIP需要支持查找,以便存储任何位置元数据,以便像Explorer这样的应用程序显示其内容。这个要求不适合我们的用例,所以如果需要,我很乐意解决它

我看过其他图书馆,但最近似乎有一些相当糟糕的评论,没有太多关于它的活动。确实支持AES 256,但看看它使用ECB构建的源代码,我们都知道这是非常无用的。这让我现在相信,我唯一的选择可能是将多个文件连同一些元数据一起写入zip,这些元数据可以标识它们在流中的位置(我显然无法
Seek
找到这些文件,但这不是问题)

希望有助于澄清我想要实现的目标:

我有多个文件(A、B、C),我想创建一个zip存档(D),然后在同一个过程(De)中加密它。所有这些都应完成,而不在磁盘上存储数据。我目前正在使用
FileStream
s作为测试,很可能以后这些将是
MemoryStream
s,以防止未加密的数据接触文件系统


我错过什么了吗?这是可能的吗?

为了提供一个答案,我实际上接受了@JamesKPolks的建议,编写自己的库来对多个文件进行压缩和加密

我无权提供实际的基于代码的解决方案,而且它是根据我们的特定需求定制的,因此可能对其他人来说不是最有用的。然而,简而言之,采取了以下方法

该文件分为两个主要部分:

1。纯文本

四,

2。加密的

然后将其分为两部分:

2.1。元数据

要存储的条目的名称,在末尾填充,以帮助根据固定的块大小进行读取

2.2。内容

在2.1元数据中,数据项本身在开始时由名称项的散列标记。内容也以固定的块大小写入,带有填充

摘要

由此产生的库编写起来相当简单,但是它需要大量的前期思考。也就是说,允许从归档文件中流出来还有一点需要完成


我本希望能发布代码,但我目前没有自由。如果有人在类似的任务中需要帮助,我会非常乐意提供帮助。

所以,你有多个文件(a、B、C),你想对每个文件(a、B、C)进行压缩,然后对每个文件(ae、be、ce)进行加密,然后将这三个文件都放在一个单独的归档文件中(D)?@Forty3不,对不起,我有多个文件(a、B、C),我想创建一个zip归档文件(D)然后在相同的过程(De)中对其进行加密。所有这些都应该在不将数据存储在磁盘上的情况下完成。我目前正在使用FileStreams作为测试,很可能以后会使用memoryStream来防止未加密的数据接触文件系统。听起来你的分析是正确的。我认为问题在于zip创建/修改与流不兼容,换句话说,将文件添加到zip存档不会简单地导致数据附加到现有的zip存档。从理论上讲,假设您拥有所有文件及其长度的先验知识,那么设计一个支持您的用例的zip库是可能的。然而,我怀疑现有的图书馆中是否有这样的图书馆。准备好写你自己的了吗?请注意,压缩是可流化的,你可以创建自己的压缩存档格式,这种格式也可以流化,并且没有zip格式所具有的任何优点。@JamesKPolk我担心有人会证实你刚才所说的。谢谢你,我对这个很感兴趣。你能就你的过程给我一些建议吗?您的思考过程是什么?@jkw4703实现这一点的原因在于,现有的客户机-服务器通信机制使用受密码保护的ZIP在它们之间传输大块数据。不幸的是,这些无法满足所需的最低加密级别,因此我们开始寻找一种解决方案,以在更换时使风险降至最低。接下来,我们必须克服我们的限制,主要是不能在
加密流中
查找
。我相信我们在保持所需安全级别的同时,与ZIP文件结构非常匹配。这有用吗?