Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用file.Encrypt加密文件,然后将其解密到内存流_C#_File_Memory_Encryption - Fatal编程技术网

C# 使用file.Encrypt加密文件,然后将其解密到内存流

C# 使用file.Encrypt加密文件,然后将其解密到内存流,c#,file,memory,encryption,C#,File,Memory,Encryption,我需要实现一个简单的文件加密,然后在需要时将其解密到内存流中。 最简单的方法似乎是使用File.Encrypt,但是否可以将文件解密到内存流,而不是在将文件读取到内存流之前解密文件,从而将其公开一段时间 如果File.Encrypt不是这种情况下的最佳方式,您会推荐什么?这是我编写的第一个加密代码-请注意,虽然这是了解情况的一个良好起点,但静态密码和静态密码是一个坏主意!(感谢您突出显示此代码) 你可以解密到任何你喜欢的流,包括直接到内存流 FileInfo file = new FileInf

我需要实现一个简单的文件加密,然后在需要时将其解密到内存流中。 最简单的方法似乎是使用File.Encrypt,但是否可以将文件解密到内存流,而不是在将文件读取到内存流之前解密文件,从而将其公开一段时间


如果File.Encrypt不是这种情况下的最佳方式,您会推荐什么?

这是我编写的第一个加密代码-请注意,虽然这是了解情况的一个良好起点,但静态密码和静态密码是一个坏主意!(感谢您突出显示此代码)

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

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

File.Encrypt
是操作系统的一项功能,但听起来您确实想要控制加密的方式


加密不适合心脏虚弱的人。不过要预先警告一下,在尝试此操作之前,您确实应该对常规IO和数据流有很强的了解。

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

我一直在移植该框架,以便为C#提供这样一个高级库

它可以用于加密和解密io流

使用在项目中安装

然后创建密钥集。(通过使用单独的密钥集文件,它使您能够在将来旋转密钥,并防止您意外地硬编码不应硬编码的内容。)

然后,在您的代码中,您可以使用任意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);
}

你想防御什么?我编辑了你的标题。请参阅“”,其中的共识是“不,他们不应该”。我认为
File.Encrypt
设置了一个文件系统级别的标志。因此,如果你对一个空文件调用
File.Encrypt
,然后对其进行写入,那么明文可能永远不会写入磁盘。嘿,我喜欢你的salt评论。说到这里,盐是怎么起作用的?我知道它的目的是什么,但是你能给我指出一个资源的方向来解释它是如何工作的吗?错误1)每个应用程序一个salt,而不是每个加密salt 2)一个静态密码3)没有MAC=>填充预言器4)常量IV(如果你使用合适的salt,这不会是一个问题,但是你没有)@CodesInChaos,你完全正确(除了我认为我正在设置一个IV?)这是我写的第一个加密代码,所以我认为这将是一个有用的开始。你永远不应该重用(key,IV)对。因为你的salt是常量,密码将生成(key,IV)确定配对,所以你的IV是无用的。如果你使用随机的salt,那么密钥将是唯一的,因此IV不再是真正必要的。@CodesInChaos,我已经更新了我的答案以反映你在这里所说的内容,我也不知道你可以像那样嵌套使用!你应该对每个加密使用随机IV,我更喜欢AES的3DES。你所以我忘了使用MAC。是的,我从概念上理解了加密,但我缺乏详细的理解。当然我很想学习。Dan Boneh的Coursea课程是免费的,非常好。
PM> KeyczarTool.exe create --location=path_to_key_set --purpose=crypt
PM> KeyczarTool.exe addkey --location=path_to_key_set --status=primary
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);
}