I want to store a known AES key (retrieved offline) by entering it into the application once, saving it to Cng for storage, then reference it only by name on subsequent use.
I want to save the key in the Key Storage Provider so my application won't load it into memory.
I can create (generate) a AES key (that I can retreive and create an instance of AesCng
with) like this:
CngProvider keyStorageProvider = CngProvider.MicrosoftSoftwareKeyStorageProvider;
CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters()
{
ExportPolicy = CngExportPolicies.AllowPlaintextExport,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey
};
var name = "mykey";
var algo = new CngAlgorithm("AES");
var created = CngKey.Create(algo, name, keyCreationParameters);
But how can I add my already known AES symmetric key and just reference it by name the next time I run my application to run encryption/decryption using Cng?
Using CngKey.Import
won't let me specify a name and I think I've tried all overloads but all yield some kind of error.
UPDATE:
This is a complete working example when creating a key.
// Calling code
byte[] key = //<from external input>;
byte[] data = new byte[] { 0xA, 0xB, 0xC, 0xD };
crypto.StoreKey("appkey", key);
var encryptedData = crypto.EncryptWithStoredKey("appkey", data);
// Implementation
public void StoreKey(string name, byte[] key)
{
CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters()
{
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey
};
var algo = new CngAlgorithm("AES");
// Question: How can I import the byte[] key with name "appkey" instead of generating a new key here?
CngKey.Create(algo, name, keyCreationParameters);
}
public byte[] EncryptWithStoredKey(string name, byte[] data)
{
using (var cng = new AesCng(name))
using (var encryptor = cng.CreateEncryptor())
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
return memoryStream.ToArray();
}
}
}