This project has moved. For the latest updates, please go here.

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

May 24, 2011 at 2: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)


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);
 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);
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));