我已经使用OpenSSL生成了私钥:
ARWIN-TIO:/tmp$ openssl ecparam -name prime256v1 -genkey -noout -out key.pem
ARWIN-TIO:/tmp$ cat key.pem
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIINcLTcsL/VhTBEsp1gRgHtO9lLzypm7oYjwViz3bWZCoAoGCCqGSM49
AwEHoUQDQgAE8kuZsfDhQdkkYjVRla3ShxAlsbLwOt8jUsKyebB7GGWxnBiDqRoB
bSxkkd+APIM/4+lYwIDAx5+EmIIuUIRdcA==
-----END EC PRIVATE KEY-----
而且我正在努力在Erlang的Crypto模块中使用它:
ARWIN-TIO:/tmp$ erl
Erlang/OTP 21 [erts-10.3.5.6] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Eshell V10.3.5.6 (abort with ^G)
1> Message = <<"Hello">>.
<<"Hello">>
2> PrivateKey = base64:decode("MHcCAQEEIINcLTcsL/VhTBEsp1gRgHtO9lLzypm7oYjwViz3bWZCoAoGCCqGSM49AwEHoUQDQgAE8kuZsfDhQdkkYjVRla3ShxAlsbLwOt8jUsKyebB7GGWxnBiDqRoBbSxkkd+APIM/4+lYwIDAx5+EmIIuUIRdcA==").
<<48,119,2,1,1,4,32,131,92,45,55,44,47,245,97,76,17,44,
167,88,17,128,123,78,246,82,243,202,153,...>>
3> Signature = crypto:sign(ecdsa, sha256, Message, [PrivateKey, prime256v1]).
** exception error: badkey
in function crypto:sign/5
called as crypto:sign(ecdsa,sha256,<<"Hello">>,
[<<48,119,2,1,1,4,32,131,92,45,55,44,47,245,97,76,17,44,
167,88,17,128,123,78,...>>,
prime256v1],
[])
[当我使用Erlang的Crypto模块生成密钥时,它起作用:
ARWIN-TIO:/tmp$ erl
Erlang/OTP 21 [erts-10.3.5.6] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Eshell V10.3.5.6 (abort with ^G)
1> Message = <<"Hello">>.
<<"Hello">>
2> {PublicKey, PrivateKey} = crypto:generate_key(ecdh, crypto:ec_curve(prime256v1)).
{<<4,149,38,43,104,132,214,232,147,174,88,185,96,250,185,
181,170,8,231,61,255,134,143,255,4,136,249,9,...>>,
<<130,195,50,229,108,51,72,27,219,145,250,244,116,3,52,
234,13,60,148,175,112,192,140,110,232,46,116,...>>}
3> Signature = crypto:sign(ecdsa, sha256, Message, [PrivateKey, prime256v1]).
<<48,70,2,33,0,252,243,117,254,110,176,232,185,121,156,93,
105,74,115,115,247,83,82,17,32,167,254,223,74,...>>
[我注意到,Erlang私钥比OpenSSL私钥短:
4> base64:encode(PrivateKey).
<<"gsMy5WwzSBvbkfr0dAM06g08lK9wwIxu6C50rwKaBvw=">>
哪个比用“ openssl ecparam -name prime256v1 -genkey -noout -out key.pem”生成的方法短?
为什么OpenSSL密钥不同/不能与Erlang的Crypto模块一起使用?如何使它们兼容?
谢谢。
您正在查看的是X9.62编码的私钥,该私钥另外还进行了PEM编码。您已经删除了PEM标头行并解码了基数64,因此现在只剩下X9.62编码的私钥。
您似乎正在使用OpenSSL,请先对base64进行解码,以便可以:
openssl asn1parse -inform DER -in private_prime256v1.bin
哪个会给你:
0:d=0 hl=2 l= 119 cons: SEQUENCE
2:d=1 hl=2 l= 1 prim: INTEGER :01
5:d=1 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:
835C2D372C2FF5614C112CA75811807B4EF652F3CA99BBA188F0562CF76D6642
39:d=1 hl=2 l= 10 cons: cont [ 0 ]
41:d=2 hl=2 l= 8 prim: OBJECT :prime256v1
51:d=1 hl=2 l= 68 cons: cont [ 1 ]
53:d=2 hl=2 l= 66 prim: BIT STRING
您还没有清楚地显示出公共/私有密钥的完整范围,但是看起来它们只是秘密S的“平面”表示形式,对于公共密钥,它只是未压缩的点W。
因此,这就是解析后的私钥中的OCTET STRING(最后的BIT STRING包含可选的公钥,即未压缩点W):
835C2D372C2FF5614C112CA75811807B4EF652F3CA99BBA188F0562CF76D6642
所以这解释了为什么。我不完全知道如何解析这样的结构,但是您可能不必这样做。看来Erlang已经有了一个为您执行此功能的函数,称为public_key:pem_decode
,该函数应该只接收整个openssl
生成的键。嗯,希望如此。让我知道。