Zip然后将多个文件加密到单个存档中
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zip然后将多个文件加密到单个存档中相关的知识,希望对你有一定的参考价值。
根据标题我想要获取多个文件,将它们压缩并使用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等应用程序的任何位置元数据以显示其内容。此要求不适合我们的用例,因此如果需要,我很乐意解决它。
我已经查看了其他库但是DotNetZip最近似乎有一些相当糟糕的评论,并没有很多活动。 SharpZipLib确实支持AES 256,但是查看源代码它是围绕使用ECB构建的,我们都知道ECB几乎没用。这让我相信我唯一的选择可能就是将多个文件写入zip并附带一些元数据来识别它们在流中的位置(我显然无法通过Seek
找到这些但是这是这不是问题)。
希望有助于澄清我想要实现的目标:
我有多个文件(A,B,C),我想创建一个zip存档(D),然后在同一个传递(De)中加密它。所有这一切都应该在不存储D的情况下完成。我目前正在使用FileStream
s作为测试,很可能以后这些将是MemoryStream
s以防止未加密的数据触及文件系统。
我错过了什么吗?这可能吗?
为了提供答案我实际上已经和@JamesKPolks建议编写我自己的库来进行多个文件的压缩和加密。
我无权提供基于代码的实际解决方案,而且它是根据我们的特定需求量身定制的,因此对其他人来说可能不是最有用的。但总之,采取了以下方法。
该文件分为两个主要部分:
1.明文
IV
2.加密
然后将其分为两部分:
2.1。元数据
要存储的条目的名称,在末尾填充以帮助基于固定块大小的读取。
2.2。内容
数据条目本身在开始时由2.1元数据中的名称条目的哈希标记。内容也以填充的固定块大小写入。
摘要
由此产生的库在编写时相当简单,但它已经预先考虑了相当多的想法。话虽如此,仍有一点点可以完成,允许流式传输出档案。
我希望已经发布了这些代码,但目前我并不自由。如果有人需要类似任务的帮助,我会非常乐意提供帮助。
以上是关于Zip然后将多个文件加密到单个存档中的主要内容,如果未能解决你的问题,请参考以下文章
使用 7zip 命令行实用程序解密加密的 7zip 存档文件
使用 Minizip API 从 Zip 存档中删除 Zip 条目