如何解码可以与pycryptodome库一起使用的DER / PEM格式的IPFS私钥和公钥(对于Python 3)?我从IPFS配置文件中获得的密钥是字符串,因此在这里我将不解释此过程。
我要做什么:
import base64, Crypto
publicKey = "CAASpgIwgE ... jkupAgMBAAE="
privateKey = "CAASqQkwgg ... Xmzva/Km7A=="
publicKey = base64.b64decode(publicKey)
key = Crypto.PublicKey.RSA.import_key(publicKey)
crypter = Crypto.Cipher.PKCS1_OAEPPKCS1_OAEP.new(key)
encryptedData = crypter.encrypt(data.encode())
result = base64.b64encode(encryptedData).decode()
我收到以下异常:
key = Crypto.PublicKey.RSA.importKey(publicKey)
File "/usr/local/lib/python3.6/site-packages/Crypto/PublicKey/RSA.py", line 754, in import_key
raise ValueError("RSA key format is not supported")
与privateKey类似的问题。密钥采用哪种格式,以及如何将其转换为可接受的格式?
import_key函数源代码存在:https://github.com/Legrandin/pycryptodome/blob/master/lib/Crypto/PublicKey/RSA.py#L682
答案 0 :(得分:0)
解决方案并不像乍看起来那样简单。
首先,您需要了解PrivateKey和PublicKey变量的内容不仅仅是在Base64中编码的纯键,它还是在ByteArray中序列化然后在Base64中编码的protobuf对象。为了从中获取密钥,您首先需要获取该对象的架构,reference可以使用它。
我们保存了该文件,并按照this page上的说明进行操作。简而言之,我运行命令protoc --python_out=. crypto.proto
创建了一个名为crypto_pb2.py
的Python模块。
所有准备工作已经完成,现在转到代码:
import crypto_pb2
import base64
publicKey = "CAASpgIwgE ... jkupAgMBAAE="
privateKey = "CAASqQkwgg ... Xmzva/Km7A=="
您必须首先将base64字符串解码为字节数组:
decoded = base64.b64decode(publicKey)
此函数将字节数组反序列化为熟悉的Python protobuf对象,我从this answer那里获取并进行了一些修改:
def deserialize(byte_message, proto_type):
module_, class_ = proto_type.rsplit('.', 1)
class_ = getattr(crypto_pb2, class_) # crypto_pb2 is a name of module we recently created and imported
rv = class_()
rv.ParseFromString(byte_message) # use .SerializeToString() to reverse operation
return rv
我们进一步调用该函数,传递解码后的base64及其对应的类的名称(PublicKey
为publicKey
,PrivateKey
为privateKey
), '对Data
属性感兴趣。
publicKey = deserialize(decoded, 'crypto.pb.PublicKey').Data
现在,您可以将其作为ByteArray传输到import_key函数。不要执行其他转换。
key = Crypto.PublicKey.RSA.import_key(publicKey)
crypter = Crypto.Cipher.PKCS1_OAEPPKCS1_OAEP.new(key)
encryptedData = crypter.encrypt(data.encode())
result = base64.b64encode(encryptedData).decode()