2014-03-31 41 views
14

如何從基於ECC的X509Certificate2的公鑰/私鑰中獲取與ECDsaCngECDiffieHellmanCng一起使用的CngKey從Windows證書庫中導入基於ECC的證書到CngKey中

我目前使用RSA 2048位密鑰對來簽署/加密的東西。我這樣做是通過從X509Store中抽取證書並使用標記爲不可導出的私鑰來安全存儲的。我想將當前的實現轉換爲使用ECDSA和ECDH,以便我可以使用較小的密鑰大小來獲得同等的安全性。

使用OpenSSL的我已經成功地產生ECC證書:

  1. openssl ecparam -out private.pem -name prime256v1 -genkey
  2. openssl req -new -key private.pem -x509 -nodes -days 365 -out public.cer
  3. openssl pkcs12 -export -in public.cer -inkey private.pem -out export.pfx

我已經成功地安裝了上述生成的證書到證書存儲。我可以通過指紋檢索它們,但私鑰和公鑰的加密提供程序會拋出「算法不受支持」的例外。相反,我知道我應該使用ECDsaCngECDiffieHellmanCng進行簽名/加密。但這些交易在CngKey的。

Bouncy Castle不是一個選項,因爲它需要私鑰是可導出的。

CLR Security將通過GetCngPrivateKey返回一個CngKey對,但它不能與ECDsa一起使用,因爲CLRSecurity返回的密鑰是ECDH密鑰。此外,CLR安全並沒有給我一種方法來獲取X509Certificate2的公鑰以進行簽名驗證(我甚至沒有或者不需要簽名者的私鑰)。

任何想法?我在我的智慧結束...任何幫助將很多讚賞。

回答

6

您需要從證書的公鑰創建CngKey:

certificate.PublicKey.EncodedKeyValue.RawData

的CngKey包含額外的8個字節,前4個字節用於對於所用曲線的名稱(ECS1,ECS3或ECS5),最後4個是包含關鍵字的長度。填充(32,48或66)。

刪除證書中公鑰的第一個字節(因爲ECDSA公鑰始終爲0x04)。因此,例如對於使用P-256曲線和SHA-256散列算法的ECDSA,您將獲得長度爲65個字節的公鑰。丟棄第一個字節,留下64個字節,然後前綴4個字節用於曲線,4個字節用於密鑰長度,即(編碼。ASCII)

69(E)

67(C)

83(S)

49(1)

32(密鑰長度)

現在你有公鑰(72個字節)來創建CngKey從:

變種cngKey = CngKey.Import([字節數組],CngKeyBlobFormat.EccPublicBlob) ;

var ecdsaCng = new ECDsaCng(cngKey);

你可以驗證簽名:

回報ecdsaCng.VerifyData(encodedBytes,簽字);

+1

但是,如果密鑰不是基於RSA/DSA,那麼'certificate.PublicKey'會引發問題嗎? – EricLaw