C# 如何存储用于加密文件的密钥

C# 如何存储用于加密文件的密钥,c#,encryption,cryptography,aes,rijndael,C#,Encryption,Cryptography,Aes,Rijndael,我正在玩一个将文件备份到“云”的应用程序,我想在存储文件之前对文件进行加密。我已经介绍了这一部分,但由于此应用程序将监视文件夹的更改并上载更改的文件,因此我需要存储用于加密文件的密钥。其思想是用户提供密码并生成密钥 目前,我正在使用.NET Framework进行加密。我使用RijndaelManaged类来加密/解密,使用PasswordDeriveBytes类来获取密钥 但是我应该如何保存用于加密文件的密钥呢?我还希望程序在Windows下启动,不需要用户再次输入密码。我建议您使用我描述的非

我正在玩一个将文件备份到“云”的应用程序,我想在存储文件之前对文件进行加密。我已经介绍了这一部分,但由于此应用程序将监视文件夹的更改并上载更改的文件,因此我需要存储用于加密文件的密钥。其思想是用户提供密码并生成密钥

目前,我正在使用.NET Framework进行加密。我使用RijndaelManaged类来加密/解密,使用PasswordDeriveBytes类来获取密钥


但是我应该如何保存用于加密文件的密钥呢?我还希望程序在Windows下启动,不需要用户再次输入密码。

我建议您使用我描述的非对称加密。这样,即使每个文件都将使用不同的对称密钥加密,您也只能拥有一个要保护(和备份)的私钥


您还可以让Windows(实际上是CryptoAPI)使用带有
rsacyptoServiceProvider的a(和正确的标志)来保护密钥。根据您的标志,您可以为登录的用户提供密钥(因此它与用户登录密码一样安全)。

旨在解决此问题

我建议避免使用非对称加密来加密文件。非对称加密在计算上比同等强度的对称加密算法要昂贵得多。对于加密大文件,我建议在任何一天使用AES而不是RSA

至于你的问题-Gaurav提到的数据保护API(DPAPI)是你在Windows上的最佳选择

DPAPI提供和。前者允许您保护内存中的机密,后者为保存到磁盘的机密提供保护。API负责为您进行加密和解密,并且(取决于指定的范围)将保护您的数据不被其他用户或其他机器访问/解密

要在您的场景中使用DPAPI,我建议使用用户密码,生成对称加密密钥(例如),使用DPAPI存储该密钥,并限制对当前用户的访问

您的应用程序可以使用该密钥加密所有上载。应用程序可以在不重新提示用户的情况下获取密钥,并且用户可以在新系统上重新生成密钥

一个缺点是,同样由同一用户执行的恶意应用程序可能会获得密钥。为了防止这种情况,必须在&中提供额外的熵(实际上是一种盐)。然而,实现这一点可能会偏离您的目标,因为现在您需要提示用户输入一些看起来非常像密码的东西

还有:有趣的阅读:

你也可以从Backblaze找到这篇文章,读起来很有趣。虽然他们没有解释他们如何支持您的场景(加密上传,云提供商无法破译-只是他们提供这样的服务):

免责声明:我是一位满意的Backblaze客户,但我与他们的服务没有任何其他关联


注:一定要花时间标出可接受的答案。社区将奖励您。

我同意DPAPI的建议。下面是一些代码来演示如何使用ProtectedData类。这与您的具体场景并不完全相关,但您可以推断

byte[] GetEncryptionKey()
{
    var path = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        AppDomain.CurrentDomain.FriendlyName,
        "nothing interesting... move along",
        "top secret encryption key");

    Debug.WriteLine("Encryption Key File: " + path);

    var file = new FileInfo(path);
    if (!file.Directory.Exists)
        file.Directory.Create();

    // determine if current user of machine
    // or any user of machine can decrypt the key
    var scope = DataProtectionScope.CurrentUser;

    // make it a bit tougher to decrypt 
    var entropy = Encoding.UTF8.GetBytes("correct horse battery staple :)");

    if (file.Exists)
    {
        return ProtectedData.Unprotect(
            File.ReadAllBytes(path), entropy, scope);       
    }

    // generate key
    byte[] key;
    using(var rng = RNGCryptoServiceProvider.Create())
        key = rng.GetBytes(1024);

    // encrypt the key
    var encrypted = ProtectedData.Protect(key, entropy, scope);

    // save for later use   
    File.WriteAllBytes(path, encrypted);

    return key;
}

这可能有助于谢谢你,非常详细的回答。经过几次测试,这似乎正是我所需要的:)对此答案有一个很好的提示:如果应用程序用户更改其窗口,受保护的数据(此处为密钥)将不会有用,因此,如果数据非常重要且窗口可能会更改,则最好保留密钥使用普通的加密方法能够在这种情况下对其进行解密(例如,您可以为密钥enc/dec算法提供恒定密码)。