问题描述
我正在运行 Python 3.8.2 版并使用 pycryptodome 3.9.9 版以 PEM 编码导入 ECC 私钥,以便稍后对一些数据进行签名。
以下 EC 私钥是一个示例密钥,我将其用于多个跨平台项目 [例如Java、PHP、NodeJs] 并且它可以正常工作(它是 NIST P-256 / secp256r1-key)键:
ecprivatekey.pem:
-----BEGIN EC PRIVATE KEY-----
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCAU2f8tzo99Z1HoxJlY
96yXUhFY5vppVjw1iPKRfk1wHA==
-----END EC PRIVATE KEY-----
在 Python 中使用此密钥失败:
Invalid DER encoding inside the PEM file
我看到使用 ASN1-dumper:
0 65: SEQUENCE {
2 1: INTEGER 0
5 19: SEQUENCE {
7 7: OBJECT IDENTIFIER ecpublicKey (1 2 840 10045 2 1)
16 8: OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7)
: }
26 39: OCTET STRING,encapsulates {
28 37: SEQUENCE {
30 1: INTEGER 1
33 32: OCTET STRING
: 14 D9 FF 2D CE 8F 7D 67 51 E8 C4 99 58 F7 AC 97
: 52 11 58 E6 FA 69 56 3C 35 88 F2 91 7E 4D 70 1C
: }
: }
: }
现在我使用 OpenSSL 将此 PEM 文件转换为 DER 文件,并将结果编码为 Base64 以在 Python 中使用:
openssl ec -in ecprivatekey.pem -outform DER -out ecprivatekey.der
openssl enc -base64 -in ecprivatekey.der -out ecprivatekey.der.base64
结果如下:
MDECAQEEIBTZ/y3Oj31nUejEmVj3rJdSEVjm+mlWPDWI8pF+TXAcoAoGCCqGSM49AwEH
运行我的导入它会成功导入密钥:
EccKey(curve='NIST P-256',point_x=93061505133516819612094413624227760091937004899246228970231210633982641184160,point_y=83370390147869481338300161558578623699120044123289243047585106101294907287413,d=9431423964991629169983079041344798030398447908105071875075159616703093895196)
最后一步是将 DER 编码的文件“重新转换”为 PEM 编码的文件:
openssl ec -inform DER -in ecprivatekey.der -outform PEM -out ecprivatekey2.pem
这些是转换和 ASN1 转储的结果:
-----BEGIN EC PRIVATE KEY-----
MDECAQEEIBTZ/y3Oj31nUejEmVj3rJdSEVjm+mlWPDWI8pF+TXAcoAoGCCqGSM49
AwEH
-----END EC PRIVATE KEY-----
0 49: SEQUENCE {
2 1: INTEGER 1
5 32: OCTET STRING
: 14 D9 FF 2D CE 8F 7D 67 51 E8 C4 99 58 F7 AC 97
: 52 11 58 E6 FA 69 56 3C 35 88 F2 91 7E 4D 70 1C
39 10: [0] {
41 8: OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7)
: }
: }
可以导入重新转换的密钥:
EccKey(curve='NIST P-256',d=9431423964991629169983079041344798030398447908105071875075159616703093895196)
所以我的问题是:我的 EC 私钥有什么“错误”,以至于它在 Java/PHP/NodeJs-Crypto/WebCrypto 中运行但不在 Python 中运行?或者更好:如何在没有任何进一步(外部)转换的情况下在 Python 中导入我现有的 EC 私钥?
这是我的导入测试程序的完整源代码:
from Crypto.PublicKey import ECC
import base64
print("Python import EC private key\n")
# trying to import the original EC private key
ecPrivateKeyPem = """-----BEGIN EC PRIVATE KEY-----
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCAU2f8tzo99Z1HoxJlY
96yXUhFY5vppVjw1iPKRfk1wHA==
-----END EC PRIVATE KEY-----
"""
try:
ecPrivateKey = ECC.import_key(ecPrivateKeyPem)
print(ecPrivateKey)
except ValueError as e:
print(e)
#error: Invalid DER encoding inside the PEM file
# import of the DER encoded EC private key runs:
ecPrivateKeyDerBase64 = """MDECAQEEIBTZ/y3Oj31nUejEmVj3rJdSEVjm+mlWPDWI8pF+TXAcoAoGCCqGSM49AwEH"""
ecPrivateKeyDer = base64.decodebytes(ecPrivateKeyDerBase64.encode("ascii"))
try:
ecPrivateKey = ECC.import_key(ecPrivateKeyDer)
print("\necPrivateKeyDer")
print(ecPrivateKey)
except ValueError as e:
print(e)
ecPrivateKeyPem2 = """-----BEGIN EC PRIVATE KEY-----
MDECAQEEIBTZ/y3Oj31nUejEmVj3rJdSEVjm+mlWPDWI8pF+TXAcoAoGCCqGSM49
AwEH
-----END EC PRIVATE KEY-----
"""
try:
ecPrivateKey2 = ECC.import_key(ecPrivateKeyPem2)
print("\necPrivateKeyPem2")
print(ecPrivateKey2)
except ValueError as e:
print(e)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)