Full Backup & Recovery of RSA Keypair ( CNGKey.Import CngKeyBlobFormat does not work)

May 24, 2011 at 1:07 PM
Guys, I need your help please!  .NET CNG makes me crazy...

 

I'm using your .NET wrappers for CNG and what I'm trying to achive is: backup & recovery of CNG RSA keypairs using "Microsoft Software Key Storage Provider"  (it should work on different Windows systems, sothat OpaqueTransportBlob is not useful)

 

Problem:
Why CNGKey.Import() runs without throwing any exception but the RSA-2048 keypair is not imported/created? Shoud I try with LEGACY_RSAPRIVATE_BLOB?
Tell me pls what the hell I'm doing wrong??? I have no ideas anymore and I'm tired... ((( 

 

Code built with .NET 3.5
Development/Test systems: Windows Server 2008 R2, Windows 7 SP1

 

How do I do it and what happens:
1) Create RSA-2048 Keypair in CNG KSP (works fine!)
if (!CngKey.Exists(KeyName, myKSP))
{
 CngProvider myKSP = new CngProvider(KSPName);
 CngKeyCreationParameters keyParams = new CngKeyCreationParameters();
 
 keyParams.ExportPolicy = CngExportPolicies.AllowPlaintextExport;
 keyParams.KeyCreationOptions = CngKeyCreationOptions.None;
 keyParams.Provider = myKSP;

 CngProperty keySizeProperty = new CngProperty("Length", BitConverter.GetBytes(KeySize), CngPropertyOptions.None);
 keyParams.Parameters.Add(keySizeProperty);
 CngKey myCNGKey = CngKey.Create(CngAlgorithm2.Rsa, KeyName, keyParams);
}
 
2) Export/backup RSA-2048 Keypair (Private/Public) into binary file (works w/o errors)
CngKey myMasterKey = CngKey.Open(tmpKEY, new CngProvider(tmpKSP));

//Different keyblob formats are tested
//buffer = myMasterKey.Export(CngKeyBlobFormat.OpaqueTransportBlob);
//buffer = myMasterKey.Export(CngKeyBlobFormat.GenericPrivateBlob);
//buffer = myMasterKey.Export(new CngKeyBlobFormat("RSAPRIVATEBLOB"));
//buffer = myMasterKey.Export(new CngKeyBlobFormat("RSAFULLPRIVATEBLOB"));

CNGKSPUtility.writeByteArrayToFile(buffer, saveFileDialog.FileName);
 
3) Delete the exported keypair (works, what a surpise)
CngKey tmpK = CngKey.Open(KeyName, myKSP);
tmpK.Delete()
 
4) Import (works only with OpaqueTransportBlob, but not with other options - the import operations completes w/o errors but key isn't in KSP)
CNGKSPUtility.writeByteArrayToFile(buffer, saveFileDialog.FileName);

buffer = CNGKSPUtility.ReadByteArrayFromFile(openFileDialog.FileName);

//Works fine but useless, because keyblob must be importable on another system
//CngKey.Import(buffer, CngKeyBlobFormat.OpaqueTransportBlob, new CngProvider(tmpKSP));

//No errors but the key is not created in KSP after import
//CngKey.Import(buffer, CngKeyBlobFormat.GenericPrivateBlob, new CngProvider(tmpKSP));

//No errors but the key is not created in KSP after import
//CngKey.Import(buffer, new CngKeyBlobFormat("RSAPRIVATEBLOB"), new CngProvider(tmpKSP));

//No errors but the key is not created in KSP after import
//CngKey.Import(buffer, new CngKeyBlobFormat("RSAFULLPRIVATEBLOB"), new CngProvider(tmpKSP));