.NETのコア1.0と.NET Framework 4.7ECParameters持っていますキーをインポート/エクスポートする構造体。 ToByteArray()
メソッドを呼び出すとCNG EccPublicBlobが生成され、SEC-1 ECParametersフォーマットとはほとんど関係がありません。
ハッシュアルゴリズムとして指定したにもかかわらず、secp384r1/NIST P-384を使用すると仮定します。他のカーブが必要な場合は、いくつかの翻訳を行う必要があります。
(.NET)ECParameters構造体は、開始に役立ちます。これをファイルに変換するには、PEMでエンコードされたDERでエンコードされたASN.1ベースの構造に変換する必要があります。
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier {{ECPKAlgorithms}} (WITH COMPONENTS {algorithm, parameters}),
subjectPublicKey BIT STRING
}
ECPKAlgorithms ALGORITHM ::= {
ecPublicKeyType |
ecPublicKeyTypeRestricted |
ecPublicKeyTypeSupplemented |
{OID ecdh PARMS ECDomainParameters {{SECGCurveNames}}} |
{OID ecmqv PARMS ECDomainParameters {{SECGCurveNames}}},
...
}
ecPublicKeyType ALGORITHM ::= {
OID id-ecPublicKey PARMS ECDomainParameters {{SECGCurveNames}}
}
ECDomainParameters{ECDOMAIN:IOSet} ::= CHOICE {
specified SpecifiedECDomain,
named ECDOMAIN.&id({IOSet}),
implicitCA NULL
}
An elliptic curve point itself is represented by the following type
ECPoint ::= OCTET STRING
whose value is the octet string obtained from the conversion routines given in Section 2.3.3.
蒸留:私たちは以下の構造を得るSEC 1 v2.0で
(あなたはNIST P-256/521分の384にこだわっている場合でも、あなたはバイト[]あなたが現在持っているとそれを行うことができます)
SEQUENCE (AlgorithmIdentifier)
30 xx [yy [zz]]
OBJECT IDENTIFIER id-ecPublicKey (1.2.840.10045.2.1)
06 07 2A 86 48 CE 3D 02 01
OBJECT IDENTIFIER secp384r1 (1.3.132.0.34)
06 05 2B 81 04 00 22
:関連部分には、このダウンは、あなたAlgorithmIdentifierはあなたがカーブを変更しないある一定のデータが含まれてい
SEQUENCE (SubjectPublicKeyInfo)
SEQUENCE (AlgorithmIdentifier)
OBJECT IDENTIFIER id-ecPublicKey
OBJECT IDENTIFIER secp384r1 (or whatever named curve you're using)
BIT STRING
public key encoded as ECPoint
を作成する必要があります
、私たちは今、ペイロードにあったバイト数を数えることができます:16(0x10を)ので、私たちは、長さを埋める:
30 10 06 07 2A 86 48 CE 3D 02 01 06 05 2B 81 04
00 22
誰もが理解し、公開鍵暗号は、「非圧縮ポイント」、です
04 th eb yt es of x. th eb yt es of y.
は、DERでエンコードされているほとんどのものとは異なり、1つのパス:)でこれを行うことができますので、あまりにも、与えられた曲線のための固定サイズを持っていること、が判明しました。 secp384r1の場合、x座標とy座標はそれぞれ384ビット値、つまり(384 + 7)/ 8 == 48バイトであるため、ECPointは48 + 48 + 1 == 97(0x61)バイトです。次に、1つのペイロードバイトと長さとタグを追加するBIT STRINGにラップする必要があります。そこで、我々が得る:
$ openssl ec -pubin -text -noout
read EC key
(paste)
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEwpbxYmcsNvr14D8k+0VQCkSY4WCV/3V10AiIq7sFdmUX
9+0DMuuLDmcKjL1ZFEFk0yHCPpY+pdkYtzPwE+dsApCPT3Ljk0AxHQBTSo4yjwsElMoA4Mtp8Qdo
LZD1Nx6v
-----END PUBLIC KEY-----
Private-Key: (384 bit)
pub:
04:c2:96:f1:62:67:2c:36:fa:f5:e0:3f:24:fb:45:
50:0a:44:98:e1:60:95:ff:75:75:d0:08:88:ab:bb:
05:76:65:17:f7:ed:03:32:eb:8b:0e:67:0a:8c:bd:
59:14:41:64:d3:21:c2:3e:96:3e:a5:d9:18:b7:33:
f0:13:e7:6c:02:90:8f:4f:72:e3:93:40:31:1d:00:
53:4a:8e:32:8f:0b:04:94:ca:00:e0:cb:69:f1:07:
68:2d:90:f5:37:1e:af
ASN1 OID: secp384r1
NIST CURVE: P-384
:
private static byte[] s_secp384r1PublicPrefix = {
// SEQUENCE (SubjectPublicKeyInfo, 0x76 bytes)
0x30, 0x76,
// SEQUENCE (AlgorithmIdentifier, 0x10 bytes)
0x30, 0x10,
// OBJECT IDENTIFIER (id-ecPublicKey)
0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01,
// OBJECT IDENTIFIER (secp384r1)
0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22,
// BIT STRING, 0x61 content bytes, 0 unused bits.
0x03, 0x62, 0x00,
// Uncompressed EC point
0x04,
}
...
using (ECDiffieHellman ecdh = ECDiffieHellman.Create())
{
ecdh.KeySize = 384;
byte[] prefix = s_secp384r1PublicPrefix;
byte[] derPublicKey = new byte[120];
Buffer.BlockCopy(prefix, 0, derPublicKey, 0, prefix.Length);
byte[] cngBlob = ecdh.PublicKey.ToByteArray();
Debug.Assert(cngBlob.Length == 104);
Buffer.BlockCopy(cngBlob, 8, derPublicKey, prefix.Length, cngBlob.Length - 8);
// Now move it to PEM
StringBuilder builder = new StringBuilder();
builder.AppendLine("-----BEGIN PUBLIC KEY-----");
builder.AppendLine(
Convert.ToBase64String(derPublicKey, Base64FormattingOptions.InsertLineBreaks));
builder.AppendLine("-----END PUBLIC KEY-----");
Console.WriteLine(builder.ToString());
}
は、私には、OpenSSLにそこから得た出力を実行します