Reputation: 13762
This is related to .NET / C#. Lets assume there is a certificate + private key (P521 ECC one) inside a PFX or a PKCS#12 file. We have loaded this certificate and it's private key into the Windows certificate store by installing it (either double clicking the PFX or running certutil -f -p myPfxPassword -importPFX MY SomeEcCert.pfx
). I have noted that if the certificate is compatible (eg. p521 curve), it is automatically installed as a CNG certificate/key.
Now, how can I load the private key into a CngKey so I can then use it inside the ECDiffieHellmanCng
class? I would also like to load the X509 (CNG) certificate to read it's serial #, issuer, common name etc for some bookkeeping.
var myCngKey = SomehowLoadTheCngKey("my ecc certificate"); // <== ??
var myDH = new ECDiffieHellmanCng(myCngKey);
Upvotes: 3
Views: 2518
Reputation: 13762
Well, .NET's doesn't have a good API into CNG. If you even scratch the surface of their API you immediately see it's kinda ridiculous, especially considering both are from Microsoft and CNG is the most serious of all Crypto APIs on the entire windows platform.
So you need to use CLRSecurity which provides C# interfaces (via P/Invoke) into the C++ CNG API. Even with that it's not the nicest of API designs; but it helps.
// Load the cert, many ways, one implementation
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindBySubjectName, "My cert subject name", true);
store.Close();
if (certs.Count > 0)
cert = certs[0];
else
return;
// Magic happens here! We load the private CngKey (if it exists)
// You need CLR Security for this, it manages the P/Invoke
// into the C++ api behind the scenes.
var pvtCngKey = cert.GetCngPrivateKey();
// Create the DiffieHellman helper
var ecDh = new ECDiffieHellmanCng(ourPvtEcCngKey)
{
KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash,
HashAlgorithm = CngAlgorithm.Sha256
};
ECDiffieHellmanCngPublicKey theirPubCngKey = LoadOtherPartiesCngPublicKey(theirCert);
byte[] symKey = ecDh.DeriveKeyMaterial(theirPubCngKey);
Upvotes: 2