【发布时间】:2018-03-05 06:00:57
【问题描述】:
有由多层数据创建的文件:
//input is not always the same, but the structure is, so for example there might be h4 and h5, but I will know that, so that is not the problem
private void generalizationofwrittendata(string filename, int someint, int chunks, string outputfilename, ICryptoTransform crypt, byte[] somedata, int h1, int h2, int h3)
{
using (FileStream fs = new FileStream(outputfilename, FileMode.Create, FileAccess.Write))
{
using (BinaryWriter w = new BinaryWriter(fs, Encoding.ASCII))
{
//writing some data with binary writer
w.Write(h1);
w.Write(h2);
w.Write(h3);
using (FileStream fsIn = File.OpenRead(filename))
{
using (CryptoStream cs = new CryptoStream(fs, crypt, CryptoStreamMode.Write))
{
//writing the rest of data with crypto stream
cs.Write(somedata, 0, somedata.Length);
byte[] chunk = new byte[chunks];
int bytesRead = 0;
while ((bytesRead = fsIn.Read(chunk, 0, chunks)) > 0)
{
cs.Write(chunk, 0, bytesRead);
}
}
}
}
}
}
“写入数据的泛化”以预期的方式工作得非常好。
现在的问题是从文件中分离所有数据:
private void test(string filename, int someint, int chunks, string outputfilename, ICryptoTransform crypt)
{
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
using (BinaryReader br = new BinaryReader(fs, Encoding.ASCII))
{
//reading some not encrypted data
int h1 = br.ReadInt32();
int h2 = br.ReadInt32();
int h3 = br.ReadInt32();
using (CryptoStream cs = new CryptoStream(fs, crypt, CryptoStreamMode.Read))
{
using (BinaryReader br2 = new BinaryReader(cs, Encoding.ASCII))
{
//reading some encrypted data
byte[] somedata = br2.ReadBytes(someint);
//writing the rest of the data to file
using (FileStream fsOut = new FileStream(outputfilename, FileMode.Create))
{
byte[] chunk = new byte[chunks];
int bytesRead = 0;
while ((bytesRead = cs.Read(chunk, 0, chunks)) > 0)
{
fsOut.Write(chunk, 0, bytesRead);
}
}
}
}
}
}
}
这种方法根本行不通。只有 h1,h2,h3 可以通过这种方式接收回来。 somedata 会有所不同,写入的文件会比原始数据长,这让我认为问题出在 CryptoStream+BinaryReader 从文件开头读取。
可能你会建议我使用MemoryStream,但这仅对小文件有效,因此会导致内存超出范围异常。
我发现的唯一其他解决方案是 SubStream 实现,但不幸的是,当我在“fs”和“cs”之间使用它时,它会导致错误的“somedata”并且结果文件也有错误的数据。
也许有一种方法可以使用Memory-Mapped Files 来做到这一点?但我不太确定我需要如何以这种方式处理它。 或者我可能遗漏了其他东西,因为使用 BinaryWriter 然后 CryptoStream 写入“generalizationofwrittendata”似乎工作得很好。
更新#1:
所以在收到回复后,我重新检查了所有代码,尤其是与 ICryptoTransform 相关的代码。 ICryptoTransform 绝对不是问题,两种方法完全相同。
我注意到的另一件事是我无缘无故地使用了“BinaryReader br2”,所以我删除了它:
private void test(string filename, int someint, int chunks, string outputfilename, ICryptoTransform crypt)
{
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
using (BinaryReader br = new BinaryReader(fs, Encoding.ASCII))
{
//reading some not encrypted data
int h1 = br.ReadInt32();
int h2 = br.ReadInt32();
int h3 = br.ReadInt32();
using (CryptoStream cs = new CryptoStream(fs, crypt, CryptoStreamMode.Read))
{
//reading some encrypted data
byte[] somedata = new byte[someint];
cs.Read(somedata, 0, someint);
//writing the rest of the data to file
using (FileStream fsOut = new FileStream(outputfilename, FileMode.Create))
{
byte[] chunk = new byte[chunks];
int bytesRead = 0;
while ((bytesRead = cs.Read(chunk, 0, chunks)) > 0)
{
fsOut.Write(chunk, 0, bytesRead);
}
}
}
}
}
}
但不幸的是,这并没有解决问题,somedata 和写入文件的数据都与原始数据不同。
更新#2:
所以这是一个愚蠢的问题 - 我创建了 CreateEncryptor() 而不是 CreateDecryptor() 用于解密。
【问题讨论】:
-
someint 变量很危险,猜错它的值会产生垃圾。没有必要猜测它,只需像使用 h1...h3 一样将 somedata.Length 写入文件,以便读者始终知道正确的值。
-
为了简单的例子,我把事情过分简化了(实际代码量是 x10 的大小,由于数据的生成方式),只需考虑两个函数的输入总是相同的,包括某某。
-
噢!这真的不是你当时发布的代码;-)
标签: c# encryption stream aes padding