OpenSSL 椭圆曲线读取 DER 形式的私钥
OpenSSL Elliptic Curve reading private key in DER form
我有一个 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
如果我然后尝试使用
读取私钥
openssl ec -in private.der -inform der
我收到错误:
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:
如果我尝试:
openssl pkcs8 -in private.der -inform der
然后我得到这些错误:
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
注意如果我直接生成PEM格式:
openssl pkcs8 -in "params.pem" -inform pem -topk8 -nocrypt -out "private.pem" -outform pem
那么我读起来没问题:
openssl ec -in private.pem -inform pem
man page for openssl ec
阐明了您所观察到的行为。它提到
OpenSSL uses the private key format specified in 'SEC 1: Elliptic Curve Cryptography' (http://www.secg.org/). To convert an OpenSSL EC private key into the PKCS#8 private key format use the pkcs8 command.
您已使用命令生成 PKCS#8 格式的密钥,但随后尝试使用 openssl ec
工具将它们读取为另一种 (SEC 1) 格式。预计会失败。你应该使用 the openssl pkey
command 代替:
$ 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-----
但是,openssl ec
显然成功读取了 PEM 编码的 PKCS#8 密钥,正如您在 下提到的,那么我可以使用... 读取它。 question/surprise 与其说是:“为什么 openssl ec
不能像 DER 一样读取私钥?”,而是:“为什么 openssl ec
能像 PEM 一样读取私钥?” `. 答案在同一个手册页中:
The PEM form is the default format: it consists of the DER format base64 encoded with additional header and footer lines. In the case of a private key PKCS#8 format is also accepted.
如果你想深入挖掘,你可以按照源代码,从apps/ec.c
. It shows the use of d2i_ECPrivateKey_bio()
to read the key in the case of DER and PEM_read_bio_ECPrivateKey()
in the case of PEM. The former is a simple deserialization function. The latter contains more intelligence though, as explained in the manual开始说:
The read functions transparently handle traditional and PKCS#8 format encrypted and unencrypted keys.
这里的“繁体”指的是前面提到的SEC 1格式。
我有一个 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
如果我然后尝试使用
读取私钥openssl ec -in private.der -inform der
我收到错误:
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:
如果我尝试:
openssl pkcs8 -in private.der -inform der
然后我得到这些错误:
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
注意如果我直接生成PEM格式:
openssl pkcs8 -in "params.pem" -inform pem -topk8 -nocrypt -out "private.pem" -outform pem
那么我读起来没问题:
openssl ec -in private.pem -inform pem
man page for openssl ec
阐明了您所观察到的行为。它提到
OpenSSL uses the private key format specified in 'SEC 1: Elliptic Curve Cryptography' (http://www.secg.org/). To convert an OpenSSL EC private key into the PKCS#8 private key format use the pkcs8 command.
您已使用命令生成 PKCS#8 格式的密钥,但随后尝试使用 openssl ec
工具将它们读取为另一种 (SEC 1) 格式。预计会失败。你应该使用 the openssl pkey
command 代替:
$ 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-----
但是,openssl ec
显然成功读取了 PEM 编码的 PKCS#8 密钥,正如您在 下提到的,那么我可以使用... 读取它。 question/surprise 与其说是:“为什么 openssl ec
不能像 DER 一样读取私钥?”,而是:“为什么 openssl ec
能像 PEM 一样读取私钥?” `. 答案在同一个手册页中:
The PEM form is the default format: it consists of the DER format base64 encoded with additional header and footer lines. In the case of a private key PKCS#8 format is also accepted.
如果你想深入挖掘,你可以按照源代码,从apps/ec.c
. It shows the use of d2i_ECPrivateKey_bio()
to read the key in the case of DER and PEM_read_bio_ECPrivateKey()
in the case of PEM. The former is a simple deserialization function. The latter contains more intelligence though, as explained in the manual开始说:
The read functions transparently handle traditional and PKCS#8 format encrypted and unencrypted keys.
这里的“繁体”指的是前面提到的SEC 1格式。