Openssl 从hex DER返回二进制私钥secp256k1

Openssl 从hex DER返回二进制私钥secp256k1,openssl,private-key,encryption-asymmetric,der,Openssl,Private Key,Encryption Asymmetric,Der,我想从foo\u priv.key $ 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\u priv.key

$ 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\u 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
请注意
八进制字符串
部分中的32个字节,它们正是您要提取的字节。但是,还有关于曲线类型的附加信息以及关键帧格式的版本号。这遵循第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-----

$cat
openssl x509
只处理证书,有时处理CSR,而不是任何类型的密钥,更不用说openssl不支持的格式的密钥了。那么这个建议对您有用吗?如果您有新问题,请将其作为新问题发布。最后更新我的答案,为您提供PEM格式。如果你想让它进入一个文件,而不是
stdout
,那么在末尾添加
-out private\u key.pem
。你原来的
private\u key.pem
包括私钥和公钥。如果您使用
openssl ec-noout-text-in private_key.pem
,输出应该是相同的。我不理解您的问题。此命令生成一个新密钥(
-genkey
),因此输出肯定会与以前的密钥不同。仅使用OpenSSL工具是不可能的。您需要进行一些OpenSSL编程。也许最好问一个新问题。