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

本文关键字:加密 文件 密钥 用于 何存储 存储 | 更新日期: 2023-09-27 18:20:21

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

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

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

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

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

关于您的问题-Gaurav提到的数据保护API(DPAPI)是您在Windows上的最佳选择。如何:使用数据保护

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

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

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

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

还有:有趣的阅读:

你可能也会发现这篇来自Backblaze的文章很有趣。尽管他们没有解释他们如何支持您的场景(云提供商无法解密的加密上传,只是他们提供了这样的服务):http://blog.backblaze.com/2008/11/12/how-to-make-strong-encryption-easy-to-use/

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

PS:一定要花点时间标记可接受的答案。社区会奖励你的。

我建议您像这里描述的那样使用非对称加密。这将允许您只有一个单独的私钥来保护(和备份),即使每个文件都将使用不同的对称密钥加密。

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

DPAPI旨在解决这一挑战。

我同意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;
}