我对 C# 和加密还很陌生,所以请耐心等待。我想保存一些二进制数据(“对象” - 实际上大部分只是对象的一部分,因此我不能/不使用序列化、BinaryWriter 等),我想在内存中加密它,然后使用 FileStream 写入. 起初我想使用某种 Xor 但我不知道它很容易破解,现在我将代码更改为使用 Aes。
问题是我会有一些相对较大的文件,而且我经常只需要更改或读取 32 字节的数据。因此,我必须能够只加密一个数据块,也能够只解密所需的数据块。目前我只提出了以下解决方案。
保存数据时,我循环遍历所有数据,并在循环内部加密一大块数据并将其写入文件。在阅读时,我有一个读取数据块的循环,并且在循环内我必须声明解密器,我发现这非常低效。
这是加密和保存的代码:
//setup file stream for saving data
FileStream fStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 1024, false);
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
aes.Padding = PaddingMode.None;
ICryptoTransform encryptor = aes.CreateEncryptor(key, iv);
foreach(....)
{
//data manipulation
//encryption
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, encryptor, CryptoStreamMode.Write))
c.Write(data, 0, data.Length);
byte[] original = new byte[32];
original = m.ToArray();
fStream.Write(original, 0, original.Length);
}
key 和 iv 是硬编码的,只是为了更容易调试和解决问题,一旦这可行,我将改变 key 和 iv 的生成方式。
下面是读取和解密的代码: FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
aes.Padding = PaddingMode.None;
//reading
while (numBytesToRead > 0)
{
byte[] original = new byte[32];
byte[] data = new byte[32];
int len = fStream.Read(original, 0, 32);
//error checking ...
//decryption
ICryptoTransform decryptor = aes.CreateDecryptor(key, iv); //this is a slow operation
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, decryptor, CryptoStreamMode.Write))
c.Write(original, 0, original.Length);
data = m.ToArray();
//data manipulation ...
}
好吧,我发现在循环中创建解密器效率很低。会有相当多的数据。如果我在进入循环之前创建它,那么我无法正确解密并且必须更改加密(在循环之前声明加密流和内存流),但是我不能只加密/解密所需的数据块。也没有多少文件只需要随机读/写。例如,在某些文件中,我想从某个位置读取到文件末尾,这可能会很多。
您对此有何看法?有没有更好的方法来实现这一目标?也许不同的加密算法(一开始我想使用某种异或,但我发现它很容易“破解”)?
ps 我想在内存中加密,我必须使用可搜索的流。