How to store the key used to encrypt files

三世轮回 提交于 2019-12-03 03:06:50

I'd recommend avoiding using asymmetric encryption for encryption of your files. Asymmetric encryption is significantly more expensive (computationally) than symmetric encryption algorithms of equal strength. For encrypting large files I'd recommend AES over RSA any day.

As to your question - the Data Protection API (DPAPI) Gaurav mentions is your best bet on Windows. How to: Use Data Protection

DPAPI offers ProtectedMemory and ProtectedData. The former allowing you to protect secrets in memory, the latter affords protection for secrets persisted to disk. The API takes care of encryption & decryption for you, and (depending on the specified scope) will protect your data from access/decryption by other users or on other machines.

To use DPAPI in your scenario, I'd recommend taking the users password, generating a symmetric encryption key (e.g. PasswordDeriveBytes), storing that using DPAPI and restricting access to the current user.

Your application can use that key to encrypt all uploads. Your application can obtain the key without re-prompting the user, and the key could be regenerated by the user on a new system.

One downside would be that a malicious application also executed by the same user could potentially obtain the secret key. To protect against this scenario additional entropy (effectively a salt) must be provided in Protect & Unprotect. However implementing this will likely stray from your objective - because now you'll need to prompt the user for something that seems an awful lot like a password.

Also: interesting reading:

You may also find this post from Backblaze an interesting read. Although they do not explain how they support your scenario (encrypted uploads that the cloud provider cannot decipher - only that they offer such a service): http://blog.backblaze.com/2008/11/12/how-to-make-strong-encryption-easy-to-use/

Disclaimer: I am a satisfied Backblaze customer, but am in no other way affiliated with their service.

PS: Do take the time to mark acceptable answers. The community will reward you.

I suggest you to use asymmetric encryption like I described here. That will allow you to only have one single private key to protect (and backup) even while every file will be encrypted with a different symmetric key.

You can also let Windows (actually CryptoAPI) protect the key using a CspParameters (and the right flags) with the RSACryptoServiceProvider. Depending on your flags you can have the key will be available for the logged on user (so it gets as secure as the user login password).

DPAPI was designed to solve this challenge.

I concur with the DPAPI suggestion. Here's some code to demonstrate how to use the ProtectedData class. This isn't exactly germane for your exact scenario, but you can extrapolate.

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!