我正在开发一个进程,用于压缩和加密桌面应用程序中的字节数组,并通过WebMethod将其发送到我的web应用程序,然后将其解压缩/解加密回字节数组。我目前正试图用SharpZipLib来实现这一点。文件的压缩似乎如预期的那样正常工作。我能够将文件保存到磁盘,并使用7zip进行解压缩,没有问题。
我遇到的问题是,当我在我的web服务器上接收到字节数组并试图提取它时。
我使用CompressData方法压缩桌面端的数据。
private byte[] CompressData(byte[] data, string password)
{
MemoryStream input = new MemoryStream(data);
MemoryStream ms = new MemoryStream();
ZipOutputStream os = new ZipOutputStream(ms);
os.SetLevel(9);
if (!string.IsNullOrEmpty(password)) os.Password = password;
ZipEntry entry = new ZipEntry("data")
{
DateTime = DateTime.Now
};
if (!string.IsNullOrEmpty(password)) entry.AESKeySize = 256;
os.PutNextEntry(entry);
StreamUtils.Copy(input, os, new byte[4096]);
os.CloseEntry();
os.IsStreamOwner = false;
os.Close();
ms.Position = 0;
return ms.ToArray();
}
我使用以下代码提取服务器端的数据(几乎逐字从SharpZipLib示例中提取):
private byte[] DoRebuildData(byte[] data, string password)
{
MemoryStream inStream = new MemoryStream(data);
MemoryStream outputMemStream = new MemoryStream();
ZipOutputStream zipOut = new ZipOutputStream(outputMemStream)
{
IsStreamOwner = false // False stops the Close also Closing the underlying stream.
};
zipOut.SetLevel(3);
zipOut.Password = password; // optional
RecursiveExtractRebuild(inStream, zipOut);
inStream.Close();
// Must finish the ZipOutputStream to finalise output before using outputMemStream.
zipOut.Close();
outputMemStream.Position = 0;
return outputMemStream.ToArray();
}
// Calls itself recursively if embedded zip
//
private void RecursiveExtractRebuild(Stream str, ZipOutputStream os)
{
ZipFile zipFile = new ZipFile(str)
{
IsStreamOwner = false
};
foreach (ZipEntry zipEntry in zipFile)
{
if (!zipEntry.IsFile)
continue;
String entryFileName = zipEntry.Name; // or Path.GetFileName(zipEntry.Name) to omit folder
// Specify any other filtering here.
Stream zipStream = zipFile.GetInputStream(zipEntry);
// Zips-within-zips are extracted. If you don't want this and wish to keep embedded zips as-is, just delete these 3 lines.
if (entryFileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
{
RecursiveExtractRebuild(zipStream, os);
}
else
{
ZipEntry newEntry = new ZipEntry(entryFileName);
newEntry.DateTime = zipEntry.DateTime;
newEntry.Size = zipEntry.Size;
// Setting the Size will allow the zip to be unpacked by XP's built-in extractor and other older code.
os.PutNextEntry(newEntry);
StreamUtils.Copy(zipStream, os, new byte[4096]);
os.CloseEntry();
}
}
}
预期的结果是返回服务器上的原始字节数组。
在服务器上,当涉及到行时:
Stream zipStream = zipFile.GetInputStream(zipEntry);
我收到错误“无法为AES加密流提供密码”。
我看到设置密码的唯一地方是在ZipOutputStream对象中,我已经在运行时进行了检查,这是适当设置的。
发布于 2019-08-10 08:00:02
解压缩时,必须将密码分配给password
-property of ZipFile
-instance,即必须在RecursiveExtractRebuild
-method中设置密码(为此,必须将密码添加为附加参数):
zipFile.Password = password;
如这个例子所示。
应该注意的是,当前的DoRebuildData
-method实际上并不是解压缩数据,而是把它重新装进新的拉链里。DoRebuildData
-method中的(可选)行:
zipOut.Password = password;
不为解压缩(即旧zip)指定密码,而是为新zip定义密码。
https://stackoverflow.com/questions/57434610
复制相似问题