I need to securely persist AES key(s) to be used by the .NET AesCng algorithm. The idea is to use the CngKey class to persist the key(s) and leverage its export/import functionality to maintain the same key(s) across multiple servers.
I can create the persisted AES key
public static bool CreateContainer(string name)
{
if (CngKey.Exists(name))
{
return false;
}
CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters()
{
ExportPolicy = CngExportPolicies.AllowPlaintextExport,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey
};
CngKey cngKey = CngKey.Create(new CngAlgorithm("AES"), name, keyCreationParameters);
cngKey.Dispose();
return true;
}
and then use it to encrypt/decrypt
public static byte[] Encrypt(string keyContainerName, byte[] clearText, byte[] iv)
{
AesCng aesCng = null;
ICryptoTransform crypto = null;
byte[] cipher = null;
try
{
aesCng = new AesCng(keyContainerName);
aesCng.IV = (iv == null ? new byte[aesCng.IV.Length] : iv);
crypto = aesCng.CreateEncryptor();
cipher = crypto.TransformFinalBlock(clearText, 0, clearText.Length);
}
finally
{
if (crypto != null)
{
crypto.Dispose();
}
if (aesCng != null)
{
aesCng.Clear();
aesCng.Dispose();
}
}
return cipher;
}
public static byte[] Decrypt(string keyContainerName, byte[] cipher, byte[] iv)
{
AesCng aesCng = null;
ICryptoTransform crypto = null;
byte[] clearText = null;
try
{
aesCng = new AesCng(keyContainerName);
aesCng.IV = (iv == null ? new byte[aesCng.IV.Length] : iv);
crypto = aesCng.CreateDecryptor();
clearText = crypto.TransformFinalBlock(cipher, 0, cipher.Length);
}
finally
{
if (crypto != null)
{
crypto.Dispose();
}
if (aesCng != null)
{
aesCng.Clear();
aesCng.Dispose();
}
}
return clearText;
}
I am able to export the key
public static bool ExportKey(string name, out byte[] blob)
{
blob = null;
if (!CngKey.Exists(name))
{
return false;
}
CngKey cngKey = CngKey.Open(name);
blob = cngKey.Export(CngKeyBlobFormat.OpaqueTransportBlob);
cngKey.Dispose();
return true;
}
However, when I try to import the blob, I get a CryptographicException: The supplied handle is invalid.
public static void ImportKey(string name, byte[] blob)
{
CngKey cngKey = CngKey.Import(blob, CngKeyBlobFormat.OpaqueTransportBlob);
cngKey.Dispose();
}
I am at a loss to explain why the failure. Can anyone shed some light on this?
Thanks.