我需要实现一个简单的文件加密,然后在需要时将其解密到内存流中。最简单的方法似乎是使用 File.Encrypt 执行此操作,但是是否可以将文件解密到内存流,而不是在将文件读取到内存流之前解密文件,从而将其暴露一段时间?
如果 File.Encrypt 不是这种情况的最佳方式,您会推荐什么?
我需要实现一个简单的文件加密,然后在需要时将其解密到内存流中。最简单的方法似乎是使用 File.Encrypt 执行此操作,但是是否可以将文件解密到内存流,而不是在将文件读取到内存流之前解密文件,从而将其暴露一段时间?
如果 File.Encrypt 不是这种情况的最佳方式,您会推荐什么?
File.Encrypt
是一项操作系统功能,但听起来您真的想控制加密的完成方式。
http://msdn.microsoft.com/en-us/library/system.io.file.encrypt.aspx
// This is where the data will be written do.
MemoryStream dataStream = new MemoryStream();
// The encryption vectors
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};
// Build the encryption mathematician
using (TripleDESCryptoServiceProvider encryption = new TripleDESCryptoServiceProvider())
using (ICryptoTransform transform = encryption.CreateEncryptor(key, iv))
using (Stream encryptedOutputStream = new CryptoStream(dataStream, transform, CryptoStreamMode.Write))
using (StreamWriter writer = new StreamWriter(encryptedOutputStream))
{
// In this block, you do your writing, and it will automatically be encrypted
writer.Write("This is the encrypted output data I want to write");
}
加密不适合胆小的人。不过请注意,在尝试此操作之前,您确实应该对常规 IO 和数据流有很强的了解。
实施 Crypto 看似简单,实际上相当乏味,有很多细节,而错误的细节通常是安全方面的利用。最佳实践是使用隐藏这些细节的高级加密框架 ivs、salts、mac、比较、填充、密钥轮换,虽然高级框架不太可能有细节错误,但当它们出现时,它们会被发现并且已修复,堆栈溢出的代码片段通常不会。
我一直在移植Google Keyczar框架,因此 C# 将存在这样一个高级库。
它可用于加密和解密 io 流。
使用nuget安装在您的项目中
PM> Install-Package Keyczar -Pre
然后创建您的密钥集。(通过拥有一个单独的密钥集文件,它使您能够在将来轮换密钥,并防止您意外地对不应进行硬编码的内容进行硬编码。)
PM> KeyczarTool.exe create --location=path_to_key_set --purpose=crypt
PM> KeyczarTool.exe addkey --location=path_to_key_set --status=primary
然后在您的代码中,您可以使用任何您想要的 IO 流进行加密:
using(var encrypter = new Encrypter("path_to_key_set"))
{
encrypter.Encrypt(plaintextStream, ciphertextStream);
}
和解密:
using(var crypter = new Crypter("path_to_key_set"))
{
crypter.Decrypt(ciphertextStream, plaintextStream);
}
这是我编写的第一个加密代码 - 请注意,虽然这是了解正在发生的事情的一个很好的起点,但静态密码和静态盐是一个坏主意!(感谢您突出显示此 CodesInChaos)
您可以解密到任何您喜欢的流,包括直接到内存流...
FileInfo file = new FileInfo("SomeFile");
using (FileStream inFs = file.OpenRead())
{
using (MemoryStream outMs = new MemoryStream())
{
encryption.Decrypt(inFs, outMs);
BinaryFormatter bf = new BinaryFormatter();
targetType target= bf.Deserialize(outMs) as targetType;
}
}
其中加密是其中之一:
public class EncryptionHelper
{
static SymmetricAlgorithm encryption;
static string password = "password";
static string salt = "this is my salt. There are many like it, but this one is mine.";
static EncryptionHelper()
{
encryption = new RijndaelManaged();
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(salt));
encryption.Key = key.GetBytes(encryption.KeySize / 8);
encryption.IV = key.GetBytes(encryption.BlockSize / 8);
encryption.Padding = PaddingMode.PKCS7;
}
public void Encrypt(Stream inStream, Stream OutStream)
{
ICryptoTransform encryptor = encryption.CreateEncryptor();
inStream.Position = 0;
CryptoStream encryptStream = new CryptoStream(OutStream, encryptor, CryptoStreamMode.Write);
inStream.CopyTo(encryptStream);
encryptStream.FlushFinalBlock();
}
public void Decrypt(Stream inStream, Stream OutStream)
{
ICryptoTransform encryptor = encryption.CreateDecryptor();
inStream.Position = 0;
CryptoStream encryptStream = new CryptoStream(inStream, encryptor, CryptoStreamMode.Read);
encryptStream.CopyTo(OutStream);
OutStream.Position = 0;
}
}