将明文字节添加到 CryptoStream 的开头?
Add cleartext bytes to the beginning of a CryptoStream?
我有一个这样定义的接口:
public interface IEncryptionService
{
Stream Encrypt(Stream cleartext);
Stream Decrypt(Stream encrypted);
}
我正在使用 AesCryptoServiceProvider
实现此接口,但这里显然存在问题。 IV(初始化向量)不会在界面上返回......所以加密一些东西会很好,只要我不想再次解密它。 Decrypt() 方法根本无法工作。
我想做的是在流的开头以明文形式包含 IV,然后向其中添加 CryptoStream
,因此它本质上是带有 "header" 的加密数据,我可以剥离并用于解密流。
所以...我该怎么做?我可以很容易地创建 CryptoStream,但看起来这会加密 IV,这有点违背了目的。我可以将 CryptoStream
加载到内存中,在 IV 前面添加,然后将其作为 MemoryStream 流出,但这确实效率低下,并且会在大流中消失。
什么是好的、安全的、可扩展的做法?
这就是我的想法。看看你是如何将 IV 写入 MemoryStream,然后用加密跟随它的?然后当你要解密的时候,同样的方法先把IV拉下来
抱歉,久等了。这个正在工作。如果您不将 ms toArray(); 投射,它应该可以很好地扩展;在末尾。例如,随时写入 FileStream,您根本不需要太多内存。这只是为了在 IV 之前进行演示。
private byte[] encrypt(byte[] originalPlaintextBytes)
{
using (SymmetricAlgorithm algorithm = AesCryptoServiceProvider.Create())
{
algorithm.GenerateKey();
algorithm.GenerateIV();
byte[] iv = algorithm.IV;
byte[] key = algorithm.Key;
using (ICryptoTransform encryptor = algorithm.CreateEncryptor(key, iv))
{
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor,CryptoStreamMode.Write))
{
BinaryWriter bw = new BinaryWriter(ms);
bw.Write(iv);
cs.Write(originalPlaintextBytes, 0, originalPlaintextBytes.Length);
return ms.ToArray();
}
}
}
}
好的,不要编辑上面的代码,这里是一个随机创建 1 兆字节纯文本文件的完整程序。然后它将其加密成密文。请注意,此程序不需要 1 兆字节的内存来运行。它是完全可扩展的。同样,和以前一样,这个程序是为了演示这个概念,你最好使用大于 1 字节的 readBuffer。但我不想创建它并掩盖核心答案。我希望这有帮助。我认为这正是您需要的方法。
using System;
using System.IO;
using System.Security.Cryptography;
using System.Windows.Forms;
namespace SO_AES
{
public partial class Form1 : Form
{
Random ran = new Random();
public Form1()
{
InitializeComponent();
using (var file = File.Open("Plaintext.txt", FileMode.OpenOrCreate))
{
byte[] junkBytes = new byte[1000];
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 1000; j++)
{
junkBytes[j] = (byte)ran.Next(0, 255);
}
file.Write(junkBytes, 0, junkBytes.Length);
}
}
using (var plainTextFile = File.Open("Plaintext.txt", FileMode.Open))
{
using (var cryptoTextFile = File.Open("Crypto.txt", FileMode.OpenOrCreate))
{
encrypt(plainTextFile, cryptoTextFile);
}
}
}
void encrypt(Stream inStream, Stream outStream)
{
using (SymmetricAlgorithm algorithm = AesCryptoServiceProvider.Create())
{
algorithm.GenerateKey();
algorithm.GenerateIV();
byte[] iv = algorithm.IV;
byte[] key = algorithm.Key;
using (ICryptoTransform encryptor = algorithm.CreateEncryptor(key, iv))
{
using (CryptoStream cs = new CryptoStream(outStream, encryptor, CryptoStreamMode.Write))
{
BinaryWriter bw = new BinaryWriter(outStream);
bw.Write(iv);
byte[] readBuffer = new byte[1];
BinaryReader br = new BinaryReader(inStream);
while (br.Read(readBuffer, 0, readBuffer.Length) != 0)
{
cs.Write(readBuffer, 0, 1);
}
}
}
}
inStream.Close();
outStream.Close();
}
}
}
我有一个这样定义的接口:
public interface IEncryptionService
{
Stream Encrypt(Stream cleartext);
Stream Decrypt(Stream encrypted);
}
我正在使用 AesCryptoServiceProvider
实现此接口,但这里显然存在问题。 IV(初始化向量)不会在界面上返回......所以加密一些东西会很好,只要我不想再次解密它。 Decrypt() 方法根本无法工作。
我想做的是在流的开头以明文形式包含 IV,然后向其中添加 CryptoStream
,因此它本质上是带有 "header" 的加密数据,我可以剥离并用于解密流。
所以...我该怎么做?我可以很容易地创建 CryptoStream,但看起来这会加密 IV,这有点违背了目的。我可以将 CryptoStream
加载到内存中,在 IV 前面添加,然后将其作为 MemoryStream 流出,但这确实效率低下,并且会在大流中消失。
什么是好的、安全的、可扩展的做法?
这就是我的想法。看看你是如何将 IV 写入 MemoryStream,然后用加密跟随它的?然后当你要解密的时候,同样的方法先把IV拉下来
抱歉,久等了。这个正在工作。如果您不将 ms toArray(); 投射,它应该可以很好地扩展;在末尾。例如,随时写入 FileStream,您根本不需要太多内存。这只是为了在 IV 之前进行演示。
private byte[] encrypt(byte[] originalPlaintextBytes)
{
using (SymmetricAlgorithm algorithm = AesCryptoServiceProvider.Create())
{
algorithm.GenerateKey();
algorithm.GenerateIV();
byte[] iv = algorithm.IV;
byte[] key = algorithm.Key;
using (ICryptoTransform encryptor = algorithm.CreateEncryptor(key, iv))
{
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor,CryptoStreamMode.Write))
{
BinaryWriter bw = new BinaryWriter(ms);
bw.Write(iv);
cs.Write(originalPlaintextBytes, 0, originalPlaintextBytes.Length);
return ms.ToArray();
}
}
}
}
好的,不要编辑上面的代码,这里是一个随机创建 1 兆字节纯文本文件的完整程序。然后它将其加密成密文。请注意,此程序不需要 1 兆字节的内存来运行。它是完全可扩展的。同样,和以前一样,这个程序是为了演示这个概念,你最好使用大于 1 字节的 readBuffer。但我不想创建它并掩盖核心答案。我希望这有帮助。我认为这正是您需要的方法。
using System;
using System.IO;
using System.Security.Cryptography;
using System.Windows.Forms;
namespace SO_AES
{
public partial class Form1 : Form
{
Random ran = new Random();
public Form1()
{
InitializeComponent();
using (var file = File.Open("Plaintext.txt", FileMode.OpenOrCreate))
{
byte[] junkBytes = new byte[1000];
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 1000; j++)
{
junkBytes[j] = (byte)ran.Next(0, 255);
}
file.Write(junkBytes, 0, junkBytes.Length);
}
}
using (var plainTextFile = File.Open("Plaintext.txt", FileMode.Open))
{
using (var cryptoTextFile = File.Open("Crypto.txt", FileMode.OpenOrCreate))
{
encrypt(plainTextFile, cryptoTextFile);
}
}
}
void encrypt(Stream inStream, Stream outStream)
{
using (SymmetricAlgorithm algorithm = AesCryptoServiceProvider.Create())
{
algorithm.GenerateKey();
algorithm.GenerateIV();
byte[] iv = algorithm.IV;
byte[] key = algorithm.Key;
using (ICryptoTransform encryptor = algorithm.CreateEncryptor(key, iv))
{
using (CryptoStream cs = new CryptoStream(outStream, encryptor, CryptoStreamMode.Write))
{
BinaryWriter bw = new BinaryWriter(outStream);
bw.Write(iv);
byte[] readBuffer = new byte[1];
BinaryReader br = new BinaryReader(inStream);
while (br.Read(readBuffer, 0, readBuffer.Length) != 0)
{
cs.Write(readBuffer, 0, 1);
}
}
}
}
inStream.Close();
outStream.Close();
}
}
}