如何将ECDSA密钥转换为PEM格式

H Aßdøµ

我有一个myetherwallet私钥密码为“ testwallet”,现在我尝试按照此答案使用OpenSSL将其转换为PEM格式。

echo "a140bd507a57360e2fa503298c035854f0dcb248bedabbe7a14db3920aaacf57" | xxd -r -p - | openssl ec -inform der -pubin -noout -passin pass:testwallet -text

但是出现此错误:

read EC key
unable to load Key
140084694296480:error:0D06B08E:asn1 encoding routines:ASN1_D2I_READ_BIO:not enough data:a_d2i_fp.c:247:

更新:我没有公钥,相反,我想生成它,因此以后我还可以生成对应的以太坊地址。

dave_thompson_085

您声称您的原始密钥是OpenSSL的DER格式,不是。另外,您还声称私有密钥不是公共密钥,而是声称它是用密码加密的,无论哪种方式都是错误的:公共密钥从不加密,并且私有密钥在OpenSSL的“传统”(也称为“旧版”)算法中无法加密DER格式(对于SECG SEC1定义的ECC )。(虽然PEM更方便,但可以使用DER或PEM对PKCS8格式的OTOH私钥进行密码加密。而FWIW PKCS12格式始终对密码进行加密,并且始终对DER进行加密。)

ECC(ECDSA,ECDH,ECMQV等)键始终相对于某些“曲线”(更确切地说,是具有已标识的生成器又称为基点的曲线上的素数子组)。对于比特币,这是secp256k1,但您的问题并不只限于比特币,而此答案可能需要使用其他曲线的其他应用程序进行修改。

如果您还拥有公钥(作为未压缩的点),则可以简单地使用https://bitcoin.stackexchange.com/questions/66594/signing-transaction-with-ssl-private-key-to-pem中的解决方案连接十六进制字符串:

  a pre_string : 30740201010420
  the privkey  : (32 bytes as 64 hexits) 
  a mid_string : a00706052b8104000aa144034200 (identifies secp256k1) 
  the pubkey   : (65 bytes as 130 hexits)

然后将十六进制转换为二进制并读取为DER,或者将十六进制(可能通过二进制)转换为base64并用-----BEGIN/END EC PRIVATE KEY-----行以使其成为PEM。

如果您没有公共密钥,则可以对其进行一些修改。连接十六进制字符串

302e0201010420 privkey_32bytes_64hexits a00706052b8104000a 

并转换为二进制,然后读入openssl ec -inform d注意OpenSSL将根据给定曲线的私钥派生公钥,但实际上不会将其存储在PEM输出中,因此不能保证使用OpenSSL以外的软件进行读取。您可能需要使用openssl ec -text [-noout](为方便起见,在PEM或DER输入上)获取公钥值,然后返回并创建包含上述公钥的完整编码。


补充:由于您似乎不理解答案中的单词,因此,我将尽可能详细地说明这一点。

该值a140bd507a57360e2fa503298c035854f0dcb248bedabbe7a14db3920aaacf57是以十六进制表示的原始私钥。secp256k1私有值是32字节的二进制值;当二进制以十六进制表示时,每个字节占用两个十六进制数字,因此32个字节占用64个十六进制数字。所有这些值都是原始私钥。没有由25位数字或25个字节组成的部分具有任何有用的含义。请勿使用此值的任何25。

要构造没有公共密钥私有密钥的OpenSSL / SECG表示形式,请将代表私有密钥的十六进制字符串(全部不经修改)放在我作为第二个选项显示的其他两个十六进制字符串之间:

 302e0201010420 a140bd507a57360e2fa503298c035854f0dcb248bedabbe7a14db3920aaacf57 a00706052b8104000a 

然后将此组合的十六进制字符串转换为二进制,并将结果读取为openssl ec -inform d

$ echo 302e0201010420 a140bd507a57360e2fa503298c035854f0dcb248bedabbe7a14db3920aaacf57 a00706052b8104000a | xxd -r -p >48101258.1
$ openssl ec -inform d <48101258.1
read EC key
writing EC key
-----BEGIN EC PRIVATE KEY-----
MC4CAQEEIKFAvVB6VzYOL6UDKYwDWFTw3LJIvtq756FNs5IKqs9XoAcGBSuBBAAK
-----END EC PRIVATE KEY-----

结果为PEM格式-但PEM格式不包括您表示想要的公用密钥。要查看包括派生公钥在内的字段,请添加-text要仅查看字段而不查看PEM输出,请添加-noout

$ openssl ec -inform d <48101258.1 -text -noout
read EC key
Private-Key: (256 bit)
priv:
    a1:40:bd:50:7a:57:36:0e:2f:a5:03:29:8c:03:58:
    54:f0:dc:b2:48:be:da:bb:e7:a1:4d:b3:92:0a:aa:
    cf:57
pub:
    04:20:ea:6d:8c:e7:bc:bb:48:33:69:b2:91:1c:75:
    e5:60:2a:34:28:be:44:96:e9:7f:14:ad:52:fd:4a:
    6a:a0:e3:60:83:9c:6e:db:32:2a:22:55:7c:70:1e:
    d0:fa:1e:06:cf:57:4f:be:17:bd:6a:85:51:69:c5:
    65:96:72:cf:a9
ASN1 OID: secp256k1

现在,如果您想要一个包含公共密钥的PEM格式的密钥,请同时使用私有密钥的十六进制字符串(全部为64位数字)和新显示的公共密钥的十六进制值,并将它们插入我的第一个选项中。还要注意,ECC公钥是一个曲线点,可以有两种形式,即压缩形式或未压缩形式。此处生成的表单未压缩。如果您需要压缩,我将在以后添加。未压缩形式的secp256k1点为65个字节,以十六进制表示为130个十六进制数字。(哪种openssl ec格式为4行,每行15个字节,剩余5个字节。)

$ echo 30740201010420 a140bd507a57360e2fa503298c035854f0dcb248bedabbe7a14db3920aaacf57 a00706052b8104000aa144034200 \
> 04:20:ea:6d:8c:e7:bc:bb:48:33:69:b2:91:1c:75: e5:60:2a:34:28:be:44:96:e9:7f:14:ad:52:fd:4a: \
> 6a:a0:e3:60:83:9c:6e:db:32:2a:22:55:7c:70:1e: d0:fa:1e:06:cf:57:4f:be:17:bd:6a:85:51:69:c5: \
> 65:96:72:cf:a9 | xxd -r -p >48101258.2
$ # note xxd -r -p ignores the colons; other hex programs may need them removed instead
$ openssl ec -inform d <48101258.2
read EC key
writing EC key
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIKFAvVB6VzYOL6UDKYwDWFTw3LJIvtq756FNs5IKqs9XoAcGBSuBBAAK
oUQDQgAEIOptjOe8u0gzabKRHHXlYCo0KL5Elul/FK1S/UpqoONgg5xu2zIqIlV8
cB7Q+h4Gz1dPvhe9aoVRacVllnLPqQ==
-----END EC PRIVATE KEY-----

为DavidS添加了2019-02年:如k06a的答案中正确所示

  • 我的中间字符串的第一部分(或我的仅供私人使用的选项的整个后缀)a00706052b8104000a是一个上下文标记和a007一个OID标签的长度06052b8104000a长度1.3.132.0.10,即secp256k1

  • 我的中间字符串的其余部分a144034200是上下文标记和长度,其中包含标记长度和BITSTRING的未使用位头,BITSTRING是未压缩的原始公钥。

要做到secp256r1又称P-256或prime256v1相反,你需要将AlgId.OID改变1.2.840.10045.3.1.7其编码为a00a 0608 2a8648ce3d030107p256r1的privatekey和publickey值与p256k1的大小相同,但是AlgId更长,因此您还需要更改外部SEQUENCE的长度,

30770201010420 privatekey32bytes # note 77 
a00a06082a8648ce3d030107 a144034200 publicpoint65bytes 

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将Java密钥库转换为PEM格式

GO-如何将公钥从字符串转换为PEM格式

如何将.crt转换为.pem

如何将数据从长格式转换为宽格式

将PEM密钥转换为SSH-RSA格式

如何将原始模数和指数转换为RSA公钥(.pem格式)

如何将RSA密钥转换为ssh-rsa

如何将JWK的公钥转换为OpenSSL的PEM?

如何将PEM格式的X509证书和私钥转换为GPG格式?

如何将[]格式的列表转换为()格式

Microsoft CNG | 如何将PEM编码的ECDSA私钥导入MS密钥存储提供程序

如何将ECDSA DER编码的签名数据转换为Microsoft CNG支持的格式?

Javascript将ECDH密钥转换为ECDSA密钥

PostgreSQL:如何将JSONb密钥转换为ENUM列表?

将Amazon .pem密钥转换为Putty .ppk密钥Linux

如何将SSH公钥从PEM转换为DER格式?

如何将PEM密钥转换为RSA密钥对?

将Amazon .pem密钥转换为Putty .ppk密钥Linux

将.pem私钥转换为.key格式

如何将PEM格式的密钥(不是OpenPGP)导入GPG?

如何将base 64编码的公共密钥(.pem)转换为bytearray?

python将RSA密钥(PEM格式)转换为十六进制字符串

如何将密钥对中的值转换为列表?

如何将 osgjs 格式转换为 obj 或类似格式?

如何将 ObjectHandle 从 Pkcs11Interop 转换为 X509 证书或 Pem 格式?

如何将 ISO 日期格式转换为 yyyymmddhsi 格式?

如何将 PEM 格式的公钥转换为 CNG 密钥 blob?

如何将“日期”格式转换为 UTC 格式

如何使用 PHP 将 PEM 格式的 RSA 密钥转换为 XML 格式