Return 从十六进制 DER 到二进制私钥 secp256k1
Return to binary private key secp256k1 from hex DER
我想从 foo_priv.key
得到 private_key.pem
$ openssl ecparam -genkey -name secp256k1 -rand /dev/urandom -out private_key.pem
$ openssl ec -in private_key.pem -outform DER|tail -c +8|head -c 32 |xxd -p -c 32 > foo_priv.key
我试过
$ openssl ec -noout -text -inform DER -in foo_priv.key
read EC key
unable to load Key
$ openssl x509 -in foo_priv.key -inform DER -outform PEM
unable to load certificate
4486393452:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1220:
4486393452:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:386:Type=X509
$ cat foo_priv.key | xxd -r -p > test.bin
$ openssl ec -in test.bin -inform DER -pubin -text -noout
read EC key
unable to load Key
4456304236:error:0D06B08E:asn1 encoding routines:ASN1_D2I_READ_BIO:not enough data:a_d2i_fp.c:247:
您的 tail
和 head
提取密钥私有部分的机制只为您提供其字节。然而,OpenSSL 需要更多的东西来存储私钥信息。如果您使用的是 OpenSSL 1.1.1,则可以使用 ec
工具的 -no_public
选项提取所需的字节,如下所示:
$ openssl ec -in private_key.pem -outform DER -no_public | xxd -p -c 32
read EC key
writing EC key
302e020101042031792710388085aaec53a04072a231116dc102e63cccdf5e85
ddd875cab6be6da00706052b8104000a
将此与您原来的方法进行比较,您可以看到那里丢失了信息:
$ openssl ec -in private_key.pem -outform DER | tail -c +8 | head -c 32 | xxd -p -c 32
read EC key
writing EC key
31792710388085aaec53a04072a231116dc102e63cccdf5e85ddd875cab6be6d
一般来说,这些文件以 ASN.1 格式存储,如果不破坏它就无法轻易修改。要了解您删除的附加信息,您可以使用
$ openssl ec -in private_key.pem -no_public | openssl asn1parse
0:d=0 hl=2 l= 46 cons: SEQUENCE
2:d=1 hl=2 l= 1 prim: INTEGER :01
5:d=1 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:31792710388085AAEC53A04072A231116DC102E63CCCDF5E85DDD875CAB6BE6D
39:d=1 hl=2 l= 7 cons: cont [ 0 ]
41:d=2 hl=2 l= 5 prim: OBJECT :secp256k1
请注意 OCTET STRING
部分中的 32 个字节,这正是您要提取的字节。但是还有关于曲线类型的附加信息以及密钥格式的版本号。这遵循 RFC 5915: Elliptic Curve Private Key Structure 第 3 节中概述的私有 EC 密钥格式。没有该信息,OpenSSL 无法重建私有密钥。
如果您在阅读所有这些内容后仍想从 32 个密钥字节重建您的私钥文件,您可以使用(脆弱的)机制来实现这一点,即在前面加上 302e0201010420
并附加 a00706052b8104000a
和将结果转换为二进制形式。像
$ cat <(echo 302e0201010420) foo_priv.key <(echo a00706052b8104000a) | xxd -r -p | openssl ec -inform DER
read EC key
writing EC key
-----BEGIN EC PRIVATE KEY-----
MC4CAQEEIDF5JxA4gIWq7FOgQHKiMRFtwQLmPMzfXoXd2HXKtr5toAcGBSuBBAAK
-----END EC PRIVATE KEY-----
我想从 foo_priv.key
private_key.pem
$ openssl ecparam -genkey -name secp256k1 -rand /dev/urandom -out private_key.pem
$ openssl ec -in private_key.pem -outform DER|tail -c +8|head -c 32 |xxd -p -c 32 > foo_priv.key
我试过
$ openssl ec -noout -text -inform DER -in foo_priv.key
read EC key
unable to load Key
$ openssl x509 -in foo_priv.key -inform DER -outform PEM
unable to load certificate
4486393452:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1220:
4486393452:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:386:Type=X509
$ cat foo_priv.key | xxd -r -p > test.bin
$ openssl ec -in test.bin -inform DER -pubin -text -noout
read EC key
unable to load Key
4456304236:error:0D06B08E:asn1 encoding routines:ASN1_D2I_READ_BIO:not enough data:a_d2i_fp.c:247:
您的 tail
和 head
提取密钥私有部分的机制只为您提供其字节。然而,OpenSSL 需要更多的东西来存储私钥信息。如果您使用的是 OpenSSL 1.1.1,则可以使用 ec
工具的 -no_public
选项提取所需的字节,如下所示:
$ openssl ec -in private_key.pem -outform DER -no_public | xxd -p -c 32
read EC key
writing EC key
302e020101042031792710388085aaec53a04072a231116dc102e63cccdf5e85
ddd875cab6be6da00706052b8104000a
将此与您原来的方法进行比较,您可以看到那里丢失了信息:
$ openssl ec -in private_key.pem -outform DER | tail -c +8 | head -c 32 | xxd -p -c 32
read EC key
writing EC key
31792710388085aaec53a04072a231116dc102e63cccdf5e85ddd875cab6be6d
一般来说,这些文件以 ASN.1 格式存储,如果不破坏它就无法轻易修改。要了解您删除的附加信息,您可以使用
$ openssl ec -in private_key.pem -no_public | openssl asn1parse
0:d=0 hl=2 l= 46 cons: SEQUENCE
2:d=1 hl=2 l= 1 prim: INTEGER :01
5:d=1 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:31792710388085AAEC53A04072A231116DC102E63CCCDF5E85DDD875CAB6BE6D
39:d=1 hl=2 l= 7 cons: cont [ 0 ]
41:d=2 hl=2 l= 5 prim: OBJECT :secp256k1
请注意 OCTET STRING
部分中的 32 个字节,这正是您要提取的字节。但是还有关于曲线类型的附加信息以及密钥格式的版本号。这遵循 RFC 5915: Elliptic Curve Private Key Structure 第 3 节中概述的私有 EC 密钥格式。没有该信息,OpenSSL 无法重建私有密钥。
如果您在阅读所有这些内容后仍想从 32 个密钥字节重建您的私钥文件,您可以使用(脆弱的)机制来实现这一点,即在前面加上 302e0201010420
并附加 a00706052b8104000a
和将结果转换为二进制形式。像
$ cat <(echo 302e0201010420) foo_priv.key <(echo a00706052b8104000a) | xxd -r -p | openssl ec -inform DER
read EC key
writing EC key
-----BEGIN EC PRIVATE KEY-----
MC4CAQEEIDF5JxA4gIWq7FOgQHKiMRFtwQLmPMzfXoXd2HXKtr5toAcGBSuBBAAK
-----END EC PRIVATE KEY-----