(Erlang) 解析 ecsda public 密钥 pem 文件时出错
(Erlang) Got error while parsing ecsda public key pem file
我将私有和 public 密钥文件设为
openssl ecparam -name secp256k1 -genkey -out gen.pem
openssl ec -in gen.pem -pubout -out gen.pub
然后我检查了 .pub 文件
openssl pkey -in gen.pub -pubin -text -noout
Public-Key: (256 bit)
pub:
04:fc:de:4f:2a:77:bd:c4:f2:74:2b:ba:b5:fc:85:
e4:aa:96:a7:8e:86:14:bc:0d:fa:8e:d2:dd:50:3c:
5d:fa:f4:07:f4:17:80:49:06:19:0c:72:03:63:4e:
07:37:e9:10:64:c8:33:a4:a3:7e:26:d8:df:79:21:
d7:2d:a6:01:80
ASN1 OID: secp256k1
之后开始erl
erl
Erlang/OTP 18 [erts-7.2] [source-e6dd627] [64-bit] [smp:3:3] [async-threads:10] [hipe] [kernel-poll:false]
命令执行后
1>rr(public_key),
{ok,RawData} = file:read_file("gen.pub"),
Decoded = public_key:pem_decode(RawData),
[public_key:pem_entry_decode(X) || X <- Decoded ].
我有异常
** exception error: no match of right hand side value
{error,{asn1,{invalid_length,1}}}
in function public_key:der_decode/2 (public_key.erl, line 229)
我知道有解决方法,但我想知道是我做错了什么还是 public 关键模块有错误?
UPD 1.
当我们看结果时
{ok,#'SubjectPublicKeyInfo'{algorithm = #'AlgorithmIdentifier'{algorithm = {1,2,840,10045,2,1},
parameters = <<6,5,43,129,4,0,10>>},
subjectPublicKey = <<4,241,200,19,168,25,25,81,43,216,
89,201,37,62,66,39,166,231,161,98,
223,133,119,12,...>>}}
我们接着看:
{1,2,840,10045,2,1} 是 ecPublicKey 的 oid http://oid-info.com/get/1.2.840.10045.2.1
参数 = <<6,5,43,129,4,0,10>>
'OTP-PUB-KEY':decode('EcpkParameters',<<6,5,43,129,4,0,10>>).
给我们
{ok,{namedCurve,{1,3,132,0,10}}}
和
pubkey_cert_records:namedCurves({1,3,132,0,10}).
为我们提供源曲线 - secp256k1,以及
subjectPublicKey = <<4,241,200,19,168,25,25,81,43,216,
89,201,37,62,66,39,166,231,161,98,
223,133,119,12,...>>
是 public 密钥本身。但这是我之前所说的解决方法。
我尝试了您的步骤,它立即对我有用:
g@crayon2:~/test % openssl ecparam -name secp256k1 -genkey -out gen.pem
g@crayon2:~/test % openssl ec -in gen.pem -pubout -out gen.pub
read EC key
writing EC key
g@crayon2:~/test % openssl pkey -in gen.pub -pubin -text -noout
Public-Key: (256 bit)
pub:
04:f1:c8:13:a8:19:19:51:2b:d8:59:c9:25:3e:42:
27:a6:e7:a1:62:df:85:77:0c:ef:f7:0e:0e:19:93:
df:e6:f5:42:66:7e:ee:02:07:76:85:19:a4:a8:2d:
03:11:73:0c:b2:d4:4c:c7:0e:42:d3:30:b5:51:e3:
97:45:f8:b5:6a
ASN1 OID: secp256k1
g@crayon2:~/test % erl
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.2.1 (abort with ^G)
1> rr(public_key).
['AAControls','ACClearAttrs','AccessDescription',
'Algorithm','AlgorithmIdentifier',
'AlgorithmIdentifierPKCS-10','AlgorithmIdentifierPKCS-8',
'AlgorithmIdentifierPKCS5v2-0','AlgorithmIdentifierPKSC-7',
'AlgorithmNull','AnotherName','AttCertValidityPeriod',
'Attribute','AttributeCertificate',
'AttributeCertificateInfo','AttributePKCS-10',
'AttributePKCS-7','AttributeTypeAndValue',
'Attributes_SETOF',
'Attributes_SETOF_valuesWithContext_SETOF',
'AuthorityKeyIdentifier','BasicConstraints',
'BuiltInDomainDefinedAttribute','BuiltInStandardAttributes',
'Certificate','CertificateList','CertificationRequest',
'CertificationRequestInfo',
'CertificationRequestInfo_attributes_SETOF'|...]
2> {ok,Data}=file:read_file("gen.pub").
{ok,<<"-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE8cgTqBkZUSvYWcklPkInpuehYt+Fdwzv\n9w4OGZPf5vVCZn7u"...>>}
3> Dec=public_key:pem_decode(Data).
[#'SubjectPublicKeyInfo'{algorithm = <<48,86,48,16,6,7,42,
134,72,206,61,2,1,
6,5,43,129,4,0,10,
3,66,0,4,241,200,
...>>,
subjectPublicKey = not_encrypted}]
我的 OpenSSL 版本:
g@crayon2:~/test % openssl version
OpenSSL 1.0.1p-freebsd 9 Jul 2015
系统为FreeBSD 10.2-RELEASE
。 Erlang 版本在上面的 shell 输出中。它为我生成的 gen.pub
密钥(如果你想尝试加载它)是:
g@crayon2:~/test % cat gen.pub
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE8cgTqBkZUSvYWcklPkInpuehYt+Fdwzv
9w4OGZPf5vVCZn7uAgd2hRmkqC0DEXMMstRMxw5C0zC1UeOXRfi1ag==
-----END PUBLIC KEY-----
您是否想粘贴您的密钥以便我尝试加载它?
编辑:
抱歉,我错过了最后一步。这似乎是 OTP 代码中的错误。调用 der_decode/2
函数时将 KeyType
设置为 ECPoint
,请参阅 pem_entry_decode/1
function. But der_decode/2
expects Asn1Type
。直接调用 'OTP-PUB-KEY'
模块似乎有效:
8> Bin = hd(Dec)#'SubjectPublicKeyInfo'.algorithm.
32> 'OTP-PUB-KEY':decode('SubjectPublicKeyInfo', Bin).
{ok,#'SubjectPublicKeyInfo'{algorithm = #'AlgorithmIdentifier'{algorithm = {1,
2,840,10045,2,1},
parameters = <<6,5,43,129,4,0,10>>},
subjectPublicKey = <<4,241,200,19,168,25,25,81,43,216,
89,201,37,62,66,39,166,231,161,98,
223,133,119,12,...>>}}
不过我不确定 returns 是否合理。也许值得使用您在此问题中发布的代码作为重现步骤在 OTP 中提出错误。然后至少有能力的人会验证它为什么不起作用。我确信您遵循的步骤没有问题,就 the documentation 而言,返回并传递给其他函数的类型是可以的。
我发现 public_key.erl 中的行(第 136-137 行)
'ECPoint' ->
der_decode(KeyType, Key0)
必须替换为
'ECPoint' ->
{{KeyType,Key0},der_decode('EcpkParameters', Params)}
我将私有和 public 密钥文件设为
openssl ecparam -name secp256k1 -genkey -out gen.pem
openssl ec -in gen.pem -pubout -out gen.pub
然后我检查了 .pub 文件
openssl pkey -in gen.pub -pubin -text -noout
Public-Key: (256 bit)
pub:
04:fc:de:4f:2a:77:bd:c4:f2:74:2b:ba:b5:fc:85:
e4:aa:96:a7:8e:86:14:bc:0d:fa:8e:d2:dd:50:3c:
5d:fa:f4:07:f4:17:80:49:06:19:0c:72:03:63:4e:
07:37:e9:10:64:c8:33:a4:a3:7e:26:d8:df:79:21:
d7:2d:a6:01:80
ASN1 OID: secp256k1
之后开始erl
erl
Erlang/OTP 18 [erts-7.2] [source-e6dd627] [64-bit] [smp:3:3] [async-threads:10] [hipe] [kernel-poll:false]
命令执行后
1>rr(public_key),
{ok,RawData} = file:read_file("gen.pub"),
Decoded = public_key:pem_decode(RawData),
[public_key:pem_entry_decode(X) || X <- Decoded ].
我有异常
** exception error: no match of right hand side value
{error,{asn1,{invalid_length,1}}}
in function public_key:der_decode/2 (public_key.erl, line 229)
我知道有解决方法,但我想知道是我做错了什么还是 public 关键模块有错误?
UPD 1.
当我们看结果时
{ok,#'SubjectPublicKeyInfo'{algorithm = #'AlgorithmIdentifier'{algorithm = {1,2,840,10045,2,1},
parameters = <<6,5,43,129,4,0,10>>},
subjectPublicKey = <<4,241,200,19,168,25,25,81,43,216,
89,201,37,62,66,39,166,231,161,98,
223,133,119,12,...>>}}
我们接着看:
{1,2,840,10045,2,1} 是 ecPublicKey 的 oid http://oid-info.com/get/1.2.840.10045.2.1
参数 = <<6,5,43,129,4,0,10>>
'OTP-PUB-KEY':decode('EcpkParameters',<<6,5,43,129,4,0,10>>).
给我们
{ok,{namedCurve,{1,3,132,0,10}}}
和
pubkey_cert_records:namedCurves({1,3,132,0,10}).
为我们提供源曲线 - secp256k1,以及
subjectPublicKey = <<4,241,200,19,168,25,25,81,43,216,
89,201,37,62,66,39,166,231,161,98,
223,133,119,12,...>>
是 public 密钥本身。但这是我之前所说的解决方法。
我尝试了您的步骤,它立即对我有用:
g@crayon2:~/test % openssl ecparam -name secp256k1 -genkey -out gen.pem
g@crayon2:~/test % openssl ec -in gen.pem -pubout -out gen.pub
read EC key
writing EC key
g@crayon2:~/test % openssl pkey -in gen.pub -pubin -text -noout
Public-Key: (256 bit)
pub:
04:f1:c8:13:a8:19:19:51:2b:d8:59:c9:25:3e:42:
27:a6:e7:a1:62:df:85:77:0c:ef:f7:0e:0e:19:93:
df:e6:f5:42:66:7e:ee:02:07:76:85:19:a4:a8:2d:
03:11:73:0c:b2:d4:4c:c7:0e:42:d3:30:b5:51:e3:
97:45:f8:b5:6a
ASN1 OID: secp256k1
g@crayon2:~/test % erl
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.2.1 (abort with ^G)
1> rr(public_key).
['AAControls','ACClearAttrs','AccessDescription',
'Algorithm','AlgorithmIdentifier',
'AlgorithmIdentifierPKCS-10','AlgorithmIdentifierPKCS-8',
'AlgorithmIdentifierPKCS5v2-0','AlgorithmIdentifierPKSC-7',
'AlgorithmNull','AnotherName','AttCertValidityPeriod',
'Attribute','AttributeCertificate',
'AttributeCertificateInfo','AttributePKCS-10',
'AttributePKCS-7','AttributeTypeAndValue',
'Attributes_SETOF',
'Attributes_SETOF_valuesWithContext_SETOF',
'AuthorityKeyIdentifier','BasicConstraints',
'BuiltInDomainDefinedAttribute','BuiltInStandardAttributes',
'Certificate','CertificateList','CertificationRequest',
'CertificationRequestInfo',
'CertificationRequestInfo_attributes_SETOF'|...]
2> {ok,Data}=file:read_file("gen.pub").
{ok,<<"-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE8cgTqBkZUSvYWcklPkInpuehYt+Fdwzv\n9w4OGZPf5vVCZn7u"...>>}
3> Dec=public_key:pem_decode(Data).
[#'SubjectPublicKeyInfo'{algorithm = <<48,86,48,16,6,7,42,
134,72,206,61,2,1,
6,5,43,129,4,0,10,
3,66,0,4,241,200,
...>>,
subjectPublicKey = not_encrypted}]
我的 OpenSSL 版本:
g@crayon2:~/test % openssl version
OpenSSL 1.0.1p-freebsd 9 Jul 2015
系统为FreeBSD 10.2-RELEASE
。 Erlang 版本在上面的 shell 输出中。它为我生成的 gen.pub
密钥(如果你想尝试加载它)是:
g@crayon2:~/test % cat gen.pub
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE8cgTqBkZUSvYWcklPkInpuehYt+Fdwzv
9w4OGZPf5vVCZn7uAgd2hRmkqC0DEXMMstRMxw5C0zC1UeOXRfi1ag==
-----END PUBLIC KEY-----
您是否想粘贴您的密钥以便我尝试加载它?
编辑:
抱歉,我错过了最后一步。这似乎是 OTP 代码中的错误。调用 der_decode/2
函数时将 KeyType
设置为 ECPoint
,请参阅 pem_entry_decode/1
function. But der_decode/2
expects Asn1Type
。直接调用 'OTP-PUB-KEY'
模块似乎有效:
8> Bin = hd(Dec)#'SubjectPublicKeyInfo'.algorithm.
32> 'OTP-PUB-KEY':decode('SubjectPublicKeyInfo', Bin).
{ok,#'SubjectPublicKeyInfo'{algorithm = #'AlgorithmIdentifier'{algorithm = {1,
2,840,10045,2,1},
parameters = <<6,5,43,129,4,0,10>>},
subjectPublicKey = <<4,241,200,19,168,25,25,81,43,216,
89,201,37,62,66,39,166,231,161,98,
223,133,119,12,...>>}}
不过我不确定 returns 是否合理。也许值得使用您在此问题中发布的代码作为重现步骤在 OTP 中提出错误。然后至少有能力的人会验证它为什么不起作用。我确信您遵循的步骤没有问题,就 the documentation 而言,返回并传递给其他函数的类型是可以的。
我发现 public_key.erl 中的行(第 136-137 行)
'ECPoint' ->
der_decode(KeyType, Key0)
必须替换为
'ECPoint' ->
{{KeyType,Key0},der_decode('EcpkParameters', Params)}