【问题标题】:How to decode IPFS private and public key in DER/PEM format?如何解码 DER/PEM 格式的 IPFS 私钥和公钥?
【发布时间】:2019-06-13 17:13:59
【问题描述】:

如何解码 DER/PEM 格式的 IPFS 私钥和公钥,可以与 pycryptodome 库(对于 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

【问题讨论】:

    标签: python rsa pycrypto ipfs pycryptodome


    【解决方案1】:

    解决方案并不像我乍看之下那么简单。

    首先要明白PrivateKey和PublicKey变量的内容不仅仅是Base64编码的纯key,它是一个protobuf对象,先用ByteArray序列化,再用Base64编码。为了从中获取密钥,您首先需要获取此对象的架构,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 和它对应的类的名称(publicKeyPublicKeyprivateKeyPrivateKey),我对 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()
    

    【讨论】:

    • 链接参考已损坏,能否请您显示导入模块“crypto_pb2”的内部内容?我很感激
    猜你喜欢
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多