2017-04-01 126 views
2

我需要將OpenSSL私鑰加載到基於C#的應用程序中。如何將OpenSSL ECDSA密鑰加載到C#中?

我用來生成密鑰的命令是:

$ openssl ecparam -name prime256v1 -genkey -noout -out eckey.pem 
$ openssl ec -in eckey.pem 
read EC key 
writing EC key 
-----BEGIN EC PRIVATE KEY----- 
MHcCAQEEIMiuwhV+yI0od5E5pSU6ZGuUcflskYD4urONi1g3G7EPoAoGCCqGSM49 
AwEHoUQDQgAEe+C/M6u171u5CcL2SQKuFEb+OIEibjw1rx+S5LK4gNNePlDV/bqu 
Ofjwc5JDqXA07shbfHNIPUn6Hum7qdiUKg== 
-----END EC PRIVATE KEY----- 

openssl pkcs8 -topk8 -nocrypt -in eckey.pem -out ec2.pem 
cat ec2.pem 
-----BEGIN PRIVATE KEY----- 
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgyK7CFX7IjSh3kTml 
JTpka5Rx+WyRgPi6s42LWDcbsQ+hRANCAAR74L8zq7XvW7kJwvZJAq4URv44gSJu 
PDWvH5LksriA014+UNX9uq45+PBzkkOpcDTuyFt8c0g9Sfoe6bup2JQq 
-----END PRIVATE KEY----- 

的C#代碼我使用

string privKeyPKCS8 = @"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgyK7CFX7IjSh3kTmlJTpka5Rx+WyRgPi6s42LWDcbsQ+hRANCAAR74L8zq7XvW7kJwvZJAq4URv44gSJuPDWvH5LksriA014+UNX9uq45+PBzkkOpcDTuyFt8c0g9Sfoe6bup2JQq"; 
    byte[] privKeyBytes8 = Convert.FromBase64String(privKeyPKCS8);//Encoding.UTF8.GetBytes(privKeyEcc); 

var pubCNG = CngKey.Import(privKeyBytes, CngKeyBlobFormat.EccPrivateBlob); 

什麼是加載基於EC鑰匙插入CngKey正確的方法是什麼?


EDIT

基64編碼內的關鍵粘附到下面的格式:

ECPrivateKey ::= SEQUENCE { 
    version  INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), 
    privateKey  OCTET STRING, 
    parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 
    publicKey [1] BIT STRING OPTIONAL 
} 

使用secp256r1曲線和在未壓縮格式點的公共密鑰。

+1

您可以嘗試使用「Pkcs8PrivateBlob」格式嗎?嗯,相信這會起作用,請讓我回答,如果是這樣的話。 –

+0

@MaartenBodewes看起來像這樣做! – LamonteCristo

回答

3

使用RFC 5915: Elliptic Curve Private Key Structure中描述的格式對您的密鑰PEM/ASCII裝甲(頁眉,頁腳和底部64)進行編碼。這是由高效密碼組(SECG)首次指定的,SECG也是命名曲線secp256r1的名稱來源。該曲線由Microsoft CNG支持。

ECPrivateKey ::= SEQUENCE { 
    version  INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), 
    privateKey  OCTET STRING, 
    parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 
    publicKey [1] BIT STRING OPTIONAL 
} 

您首先需要在(更新)問題使用命令這種 「原始」 EC專用密鑰結構轉換爲PKCS#8的結構:

openssl pkcs8 -topk8 -nocrypt -in eckey.pem -out ec2.pem 

獲得:

SEQUENCE(3 elem) 
    INTEGER 0 # version of PKCS#8 structure 
    SEQUENCE (2 elem) 
    OBJECT IDENTIFIER 1.2.840.10045.2.1 # it's an EC key) 
    OBJECT IDENTIFIER 1.2.840.10045.3.1.7 # it's secp256r1 
    OCTET STRING (1 elem) # the key structure 
    SEQUENCE (3 elem) 
     INTEGER 1 # version 
     OCTET STRING (32 byte) # private key value (removed) 
     [1] (1 elem) 
     BIT STRING (520 bit) # public key value (removed) 

生成的結構沒有那麼不同,你所看到的實際上與初始結構相同。除了PKCS#8結構有一個對象標識符(OID),用於指定前面曲線本身的鍵類型和OID,而您的鍵只有OID後面的參數。兩者都在BIT STRING中攜帶(可選)公鑰值。

所以解碼器識別這種類型並返回EC私鑰。


EccPrivateBlob您正在使用需要Microsoft specific structure。另見我的問題here。它不適用於上述結構。

+1

我做了一個更改,但沒有更新問題,我運行了第二個OpenSSL命令,然後導入了該私鑰輸出。 'openssl pkcs8 -topk8 -nocrypt -in eckey.pem -out ec2.pem'。不知道這是否會改變答案/ b/c ASN1可能與您首次觀察到的不同。 – LamonteCristo

+0

done ........... – LamonteCristo

+0

是PKCS8(十六進制以上)ASN1格式?我試圖使用https://lapo.it/asn1js/解碼它,但它似乎沒有工作... – LamonteCristo