我有一个 DER 形式的 EC 私钥,我想将其转换为 PEM 形式。但我看不懂 DER 表格。
私钥生成如下:
openssl ecparam -param_enc named_curve -check -name "-secp384r1" -genkey -noout -out "params.pem" -outform pem
openssl pkcs8 -in "params.pem" -inform pem -topk8 -nocrypt -out "private.der" -outform der
Run Code Online (Sandbox Code Playgroud)
如果我然后尝试读取私钥
openssl ec -in private.der -inform der
Run Code Online (Sandbox Code Playgroud)
我收到错误:
read EC key
unable to load Key
4674530924:error:0DFFF0A8:asn1 encoding routines:CRYPTO_internal:wrong tag:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/crypto/asn1/tasn_dec.c:1144:
4674530924:error:0DFFF03A:asn1 encoding routines:CRYPTO_internal:nested asn1 error:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/crypto/asn1/tasn_dec.c:717:
4674530924:error:0DFFF03A:asn1 encoding routines:CRYPTO_internal:nested asn1 error:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/crypto/asn1/tasn_dec.c:646:Field=privateKey, Type=EC_PRIVATEKEY
4674530924:error:10FFF010:elliptic curve routines:CRYPTO_internal:EC lib:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/crypto/ec/ec_asn1.c:1353:
Run Code Online (Sandbox Code Playgroud)
如果我尝试:
openssl pkcs8 -in private.der -inform der
Run Code Online (Sandbox Code Playgroud)
然后我得到这些错误:
Error reading key
4460752492:error:0DFFF0A8:asn1 encoding routines:CRYPTO_internal:wrong tag:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/crypto/asn1/tasn_dec.c:1144:
4460752492:error:0DFFF03A:asn1 encoding routines:CRYPTO_internal:nested asn1 error:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/crypto/asn1/tasn_dec.c:317:Type=X509_ALGOR
4460752492:error:0DFFF03A:asn1 encoding routines:CRYPTO_internal:nested asn1 error:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/crypto/asn1/tasn_dec.c:646:Field=algor, Type=X509_SIG
Run Code Online (Sandbox Code Playgroud)
请注意,如果我直接生成 PEM 格式:
openssl pkcs8 -in "params.pem" -inform pem -topk8 -nocrypt -out "private.pem" -outform pem
Run Code Online (Sandbox Code Playgroud)
那么我阅读它就没有问题了:
openssl ec -in private.pem -inform pem
Run Code Online (Sandbox Code Playgroud)
的手册页openssl ec阐明了您所观察到的行为。它提到
OpenSSL 使用“SEC 1:椭圆曲线加密”( http://www.secg.org/ )中指定的私钥格式。要将 OpenSSL EC 私钥转换为 PKCS#8 私钥格式,请使用 pkcs8 命令。
您已使用命令生成 PKCS#8 格式的密钥,但随后尝试使用该openssl ec工具以其他 (SEC 1) 格式读取它们。预计这会失败。您应该使用以下命令来openssl pkey代替:
$ openssl pkey -inform DER -in private.der
-----BEGIN PRIVATE KEY-----
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCY6UCzQ6eDGo83UyWc
rCQw4caWF9Ttz/crt0/ba1AwQbJqSIHZIP+7f9HZdSY/VsOhZANiAATYTEaeRFGN
R6/LlKtEDzPHqIK6xr4Qp4Iz+t/ZXLccL3gdedDmtuSUbPiwj8/QI+gpW9MslkYf
c/Rm6OQpn4P1IagR98B+qSNW47olBlzzLP/k/Zqz71x9mgyQrBhYZWw=
-----END PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
但是,openssl ec显然成功读取了 PEM 编码的 PKCS#8 密钥,正如您在“然后我用...读取它没有问题”下提到的那样。问题/惊喜并不是:“为什么openssl ec无法将私钥读取为 DER?”,而是:“为什么能够openssl ec将私钥读取为 PEM?”。答案位于同一手册页中:
PEM 形式是默认格式:它由采用附加页眉和页脚行编码的 DER 格式 base64 组成。如果是私钥,则还接受 PKCS#8 格式。
如果您想深入挖掘,可以从apps/ec.c. 它显示了在 DER 和PEM 情况下如何使用 来d2i_ECPrivateKey_bio()读取密钥。PEM_read_bio_ECPrivateKey()前者是一个简单的反序列化函数。后者包含更多的智能,正如手册中所解释的那样:
读取函数透明地处理传统和 PKCS#8 格式的加密和未加密密钥。
这里的“传统”是指前面提到的 SEC 1 格式。
| 归档时间: |
|
| 查看次数: |
1860 次 |
| 最近记录: |