将证书密钥加载到CngKey类中以与DiffieHellman(ECDiffieHellmanCng类)一起使用

时间:2013-07-29 18:27:32

标签: c# encryption public-key-encryption diffie-hellman cng

这与.NET / C#有关。让我们假设在PFX或PKCS#12文件中有证书+私钥(P521 ECC one)。我们已将此证书及其私钥加载到Windows证书库中,方法是安装它(双击PFX或运行certutil -f -p myPfxPassword -importPFX MY SomeEcCert.pfx)。我注意到如果证书兼容(例如p521曲线),它会自动安装为CNG证书/密钥。

现在,如何将私钥加载到CngKey中,以便我可以在ECDiffieHellmanCng类中使用它?我还想加载X509(CNG)证书来读取它的序列号,发行人,普通名称等,以便进行一些簿记。

var myCngKey = SomehowLoadTheCngKey("my ecc certificate"); // <== ??
var myDH = new ECDiffieHellmanCng(myCngKey);

1 个答案:

答案 0 :(得分:1)

嗯,.NET没有一个很好的API进入CNG。如果你甚至划伤他们的API表面,你会立刻看到它有点荒谬,特别是考虑到来自微软和CNG是整个Windows平台上所有Crypto API中最严重的。

因此,您需要使用CLRSecurity将C#接口(通过P / Invoke)提供到C ++ CNG API中。即使这样,它也不是最好的API设计;但它有帮助。

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