我正在玩应用程序将文件备份到"云" :)我想在存储之前加密文件。这部分我已经介绍过,但是由于这个应用程序将监视文件夹以进行更改并上传更改的文件,我需要存储用于加密文件的密钥。这个想法是用户提供密码并生成密钥。
目前我正在使用.NET Framework进行加密。我使用RijndaelManaged类加密/解密,使用PasswordDeriveBytes类获取密钥。
但是我应该如何保留用于加密文件的密钥?我也希望程序从Windows开始,而不需要让用户再次输入密码。
答案 0 :(得分:14)
我建议避免使用非对称加密来加密文件。与同等强度的对称加密算法相比,非对称加密明显更加昂贵(计算上)。对于加密大文件,我建议任何一天使用AES over RSA。
关于你的问题 - 数据保护API(DPAPI)Gaurav提到的是你在Windows上最好的选择。 How to: Use Data Protection
DPAPI提供ProtectedMemory和ProtectedData。前者允许你保护内存中的秘密,后者可以保护持久存储到磁盘的秘密。 API负责加密&为您解密,并(取决于指定的范围)将保护您的数据不被其他用户或其他计算机访问/解密。
要在您的方案中使用DPAPI,我建议使用用户密码,生成对称加密密钥(例如PasswordDeriveBytes),使用DPAPI存储密码并限制对当前用户的访问。
您的应用程序可以使用该密钥加密所有上传。您的应用程序可以在不重新提示用户的情况下获取密钥,并且用户可以在新系统上重新生成密钥。
一个缺点是同一用户也执行的恶意应用程序可能会获得密钥。为了防止这种情况,必须在Protect&中提供额外的熵(实际上是盐)。 Unprotect。但是,实现这一点可能会偏离您的目标 - 因为现在您需要提示用户提供类似密码的内容。
另外:有趣的阅读:
你也可以从Backblaze找到这篇有趣的读物。虽然他们没有解释他们如何支持您的方案(云提供商无法破译的加密上传 - 只有他们提供此类服务): http://blog.backblaze.com/2008/11/12/how-to-make-strong-encryption-easy-to-use/
免责声明:我是一名满意的Backblaze客户,但与其服务无关。
PS:请花时间标记可接受的答案。社区会奖励你。
答案 1 :(得分:4)
我建议你像我描述的那样使用非对称加密here。这将允许您只有一个私钥来保护(和备份),即使每个文件都使用不同的对称密钥加密。
您还可以使用CspParameters
(以及正确的标记)和RSACryptoServiceProvider
让Windows(实际上是CryptoAPI)保护密钥。根据您的标记,您可以将密钥用于用户的已记录(因此它将作为安全作为用户登录密码)。
答案 2 :(得分:1)
DPAPI旨在解决这一挑战。
答案 3 :(得分: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;
}