使用文件加密文件.先加密,然后解密到内存流



我需要实现一个简单的文件加密,然后在需要时将其解密到内存流中。最简单的方法似乎是使用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和数据流有很强的了解。

实现加密看似简单,实际上相当乏味,有很多细节,而错误的细节通常是安全方面的漏洞。最好的做法是使用一个高级加密框架来隐藏这些细节ivs、salts、mac、比较、填充、密钥旋转,虽然高级框架的细节不太可能出错,但当它们出错时,它们会被发现并修复,而堆栈溢出上的代码片段通常不会。

我一直在移植GoogleKeyczar框架,所以C#会有这样一个高级库。

Keyczar dotnet

它可用于对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);
}

这是我写的第一个加密代码-请注意,尽管这是了解发生了什么的好起点,但静态密码和静态盐是个坏主意!(感谢您突出显示此代码InChaos)

你可以解密到任何你喜欢的流,包括直接解密到内存流。。。

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;  
    }
}

相关内容

  • 没有找到相关文章

最新更新