9

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

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

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

4

4 回答 4

14

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

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

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

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

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

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

另外:有趣的阅读:

您还可能会发现 Backblaze 的这篇文章很有趣。虽然他们没有解释他们如何支持您的方案(云提供商无法解密的加密上传 - 只有他们提供这样的服务): http ://blog.backblaze.com/2008/11/12/how-to-make -强加密-易于使用/

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

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

于 2012-01-17T05:53:13.280 回答
4

我建议您使用我在此处描述的非对称加密。这将允许您只有一个私钥来保护(和备份),即使每个文件都将使用不同的对称密钥进行加密。

您还可以让 Windows(实际上是 CryptoAPI 使用CspParameters带有RSACryptoServiceProvider. 根据您的标志,您可以拥有可供登录用户使用的密钥(因此它与用户登录密码一样安全)。

于 2012-01-16T14:59:45.820 回答
1

DPAPI旨在解决这一挑战。

于 2012-01-17T02:33:01.520 回答
0

我同意 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;
}
于 2014-09-09T19:07:30.663 回答