我尝试通过从给定数字(我的私钥)计算曲线上的点来创建椭圆公钥,所以我有(x,y)椭圆曲线点的坐标
我得到坐标
myPublicKeyCoordinates = myPrivateKeyValue * GPointOnCurve
Run Code Online (Sandbox Code Playgroud)
如何为我的公钥构建PEM( 或DER) 文件?
我不在乎语言(java, python, javascript, ...),
因为我想知道如何构建文件(即使我写了每个字节......)
假设您已经了解ITU-T X.680-201508(ASN.1 语言)和ITU-T X.690-201508(ASN.1 数据的 BER(和 CER)和 DER 编码),主要定义文档Elliptic Curve Keys 及其表示法是https://www.secg.org/sec1-v2.pdf来自高效密码学标准组(不是美国证券交易委员会)。
C.3 节(椭圆曲线公钥的语法)说 EC 公钥的通用传输容器是 X.509 SubjectPublicKeyInfo 结构:
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier {{ECPKAlgorithms}} (WITH COMPONENTS
{algorithm, parameters}) ,
subjectPublicKey BIT STRING
}
Run Code Online (Sandbox Code Playgroud)
可能的“算法”(实际上是指关键编码类型)是开放式集
ECPKAlgorithms ALGORITHM ::= {
ecPublicKeyType |
ecPublicKeyTypeRestricted |
ecPublicKeyTypeSupplemented |
{OID ecdh PARMS ECDomainParameters {{SECGCurveNames}}} |
{OID ecmqv PARMS ECDomainParameters {{SECGCurveNames}}},
...
}
ecPublicKeyType ALGORITHM ::= {
OID id-ecPublicKey PARMS ECDomainParameters {{SECGCurveNames}}
}
...
Run Code Online (Sandbox Code Playgroud)
ECDomainParameters 来自 C.2:
ECDomainParameters{ECDOMAIN:IOSet} ::= CHOICE {
specified SpecifiedECDomain,
named ECDOMAIN.&id({IOSet}),
implicitCA NULL
}
Run Code Online (Sandbox Code Playgroud)
C.3 提到了大约一半
椭圆曲线公钥(一个 ECPoint 类型的值,是一个 OCTET STRING)映射到一个 subjectPublicKey(一个编码为 BIT STRING 类型的值)如下: OCTET STRING 值的最高有效位成为最高有效位BIT STRING 的值,依此类推,直到 OCTET STRING 的最低有效位成为 BIT STRING 的最低有效位。
所以我们向后寻找,发现
椭圆曲线点本身由以下类型表示
Run Code Online (Sandbox Code Playgroud)ECPoint ::= OCTET STRING其值是从第 2.3.3 节中给出的转换例程中获得的八位字节字符串。
2.3.3 (Elliptic-Curve-Point-to-Octet-String Conversion) 有很多词,但支持最好的格式是不使用点压缩(而且 P != the point at infinity)
- 如果 P = (xP , yP ) != O 并且未使用点压缩,请执行以下操作:
3.1. 使用第 2.3.5 节中指定的转换例程将字段元素 xP 转换为长度为 (log2 q)/8 个八位字节的八位字节字符串 X。
3.2. 使用第 2.3.5 节中指定的转换例程将字段元素 yP 转换为长度为 (log2 q)/8 个八位字节的八位字节字符串 Y。
3.3. 输出 M = 04 16 || X|| 是。
2.3.5 是“大端字节顺序的长度足以容纳字段中的所有值”(又名“保留前导零”)的一大堆词。
所以现在我们聚会。
鉴于 secp256r1 ( d=70A12C2DB16845ED56FF68CFC21A472B3F04D7D6851BF6349F2D7D5B3452B38A)上的 FIPS 186-3 参考密钥,
Q 是 ( 8101ECE47464A6EAD70CF69A6E2BD3D88691A3262D22CBA4F7635EAFF26680A8, D8A12BA61D599235F67D9CB4D58F1783D3CA43E78F0A5ABAA624079936C0C3A9)
公钥 DER 看起来像
// SubjectPublicKeyInfo
30 XA
// AlgorithmIdentifier
30 XB
// AlgorithmIdentifier.id (id-ecPublicKey (1.2.840.10045.2.1))
06 07 2A 86 48 CE 3D 02 01
// AlgorithmIdentifier.parameters, using the named curve id (1.2.840.10045.3.1.7)
06 08 2A 86 48 CE 3D 03 01 07
// SubjectPublicKeyInfo.subjectPublicKey
03 XC 00
// Uncompressed public key
04
// Q.X
81 01 EC E4 74 64 A6 EA D7 0C F6 9A 6E 2B D3 D8
86 91 A3 26 2D 22 CB A4 F7 63 5E AF F2 66 80 A8
// Q.Y
D8 A1 2B A6 1D 59 92 35 F6 7D 9C B4 D5 8F 17 83
D3 CA 43 E7 8F 0A 5A BA A6 24 07 99 36 C0 C3 A9
Run Code Online (Sandbox Code Playgroud)
对 XA、XB 和 XC 的所有字节进行计数:
XC = 32 (QX) + 32 (QY) + 1 (0x04) + 1(未使用位为 0x00)= 66 = 0x42
XB = 19 = 0x13
XA 是 66 + 19 + 2(标签字节)+ 2(长度字节)= 89 = 0x59
(当然,如果我们的任何长度值超过 0x7F,我们就必须正确编码它们)
所以现在我们只剩下
30 59 30 13 06 07 2A 86 48 CE 3D 02 01 06 08 2A
86 48 CE 3D 03 01 07 03 42 00 04 81 01 EC E4 74
64 A6 EA D7 0C F6 9A 6E 2B D3 D8 86 91 A3 26 2D
22 CB A4 F7 63 5E AF F2 66 80 A8 D8 A1 2B A6 1D
59 92 35 F6 7D 9C B4 D5 8F 17 83 D3 CA 43 E7 8F
0A 5A BA A6 24 07 99 36 C0 C3 A9
Run Code Online (Sandbox Code Playgroud)
并且,我们验证:
$ xxd -r -p | openssl ec -text -noout -inform der -pubin
read EC key
<paste, then hit CTRL+D>
30 59 30 13 06 07 2A 86 48 CE 3D 02 01 06 08 2A
86 48 CE 3D 03 01 07 03 42 00 04 81 01 EC E4 74
64 A6 EA D7 0C F6 9A 6E 2B D3 D8 86 91 A3 26 2D
22 CB A4 F7 63 5E AF F2 66 80 A8 D8 A1 2B A6 1D
59 92 35 F6 7D 9C B4 D5 8F 17 83 D3 CA 43 E7 8F
0A 5A BA A6 24 07 99 36 C0 C3 A9
Private-Key: (256 bit)
pub:
04:81:01:ec:e4:74:64:a6:ea:d7:0c:f6:9a:6e:2b:
d3:d8:86:91:a3:26:2d:22:cb:a4:f7:63:5e:af:f2:
66:80:a8:d8:a1:2b:a6:1d:59:92:35:f6:7d:9c:b4:
d5:8f:17:83:d3:ca:43:e7:8f:0a:5a:ba:a6:24:07:
99:36:c0:c3:a9
ASN1 OID: prime256v1
NIST CURVE: P-256
Run Code Online (Sandbox Code Playgroud)
将其打印为“私钥:(256 位)”只是该工具的一个错误/怪癖,那里没有私钥。
对于指定的参数曲线,事情更难,但那些不能很好地互操作(https://tools.ietf.org/html/rfc5480#section-2.1.1说符合要求的 CA不得使用指定的参数形式,或者隐式形式,但必须使用命名形式)。
| 归档时间: |
|
| 查看次数: |
934 次 |
| 最近记录: |