嗯,.NET 没有很好的 CNG API。如果你甚至触及他们 API 的表面,你会立即发现这有点荒谬,特别是考虑到两者都来自微软,而 CNG 是整个 Windows 平台上所有 Crypto API 中最严重的。
因此,您需要使用CLRSecurity,它为 C++ CNG API 提供 C# 接口(通过 P/Invoke)。即使这样,它也不是最好的 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);