2017-04-01 15 views
2

OpenSSL秘密鍵をC#ベースのアプリケーションにロードする必要があります。C#にOpenSSL ECDSAキーをロードするにはどうすればよいですか?

私は鍵を生成するために使用されるコマンドは次のとおりです。?

$ 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#コード私はCngKeyにECベースのキーをロードするための正しい方法は何ですか

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

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

を使用していますか


EDIT

ベース64符号化内のキーは以下のフォーマットに準拠

:secp256r1曲線と圧縮されていない点形式で公開鍵を用いて

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

+1

代わりに 'Pkcs8PrivateBlob'フォーマットを試すことができますか?うーん、これがうまくいくと私は確信しています。 –

+0

@MaartenBodewesはそのようなトリックでした! – LamonteCristo

答えて

3

キーのPEM/ASCIIアーマー(ヘッダー、フッター、ベース64)は、RFC 5915: Elliptic Curve Private Key Structureに記載されている形式でエンコードされています。これは、効率的な暗号化グループ(SECG)の規格で最初に指定されました。名前付きカーブsecp256r1から名前を取得しました。曲線はMicrosoft CNGによってサポートされています。

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

ます(更新)問題のコマンドを使用して、PKCS#8の構造には、この "生" のECプライベートキー構造を変換する最初の必要性:

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秘密鍵を返します。あなたが使用していた


EccPrivateBlobMicrosoft specific structure必要です。私の質問hereも見てください。上記の構造では機能しません。

+1

私が作成した変更の1つで、質問を更新しなかったのは、2番目のOpenSSLコマンドを実行してから、その秘密鍵の出力をインポートしたことです。 'openssl pkcs8 -topk8 -nocrypt -in eckey.pem -out ec2.pem'です。これが答えを変えるかどうかわからない/ b/c ASN1は最初に観察したものとは異なる可能性があります。 – LamonteCristo

+0

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

+0

PKCS8(上記の16進数)はASN1形式ですか?私はhttps://lapo.it/asn1js/を使ってデコードしようとしましたが、うまくいきませんでした。 – LamonteCristo

関連する問題