如何使用PGPy直接解密非PGPy生成的PGP装甲字符串
已实现的通信流程
- 可主动请求获取服务端公钥,通过PGPy库使用该公钥加密我方请求,服务端可正常解密请求并返回响应
- 脚本生成的加密请求中携带我方公钥(符合服务端API规范要求),服务端提取该公钥加密响应内容后回传,脚本可正常接收到该加密响应
核心问题
PGPKey.decrypt()方法仅接收PGPMessage类型对象作为入参,不支持直接传入ASCII装甲字符串,未找到直接传入装甲字符串完成解密、或是将装甲字符串转换为PGPMessage对象的对应方法。
最初的错误实现
最初误用PGPMessage.new()做格式转换,代码如下:
def get_token_from_payload(encrypted_payload): print("Payload: ", encrypted_payload) privkey, _ = pgpy.PGPKey.from_file('private.key') message_blob = pgpy.PGPMessage.new(encrypted_payload) token_string = privkey.decrypt(message_blob).message print("Token: ", token_string) return json.load(token_string)
该实现的逻辑错误:pgpy.PGPMessage.new()会将传入的字符串作为明文内容,生成新的PGP消息对象,而非解析已有的加密装甲消息。最终解密得到的内容就是传入的原始装甲字符串,无法得到真实明文,后续JSON解析步骤也会失败。
临时落盘方案
后续通过先把装甲字符串写入文件、再从文件读取解析的方式可以正常解密,但方案存在明显冗余:
def get_token_from_payload(encrypted_payload): ep_file = open("ep.pgp", "w") ep_file.write(encrypted_payload) ep_file.close() privkey, _ = pgpy.PGPKey.from_file('private.key') message = pgpy.PGPMessage.from_file("ep.pgp") token_string = privkey.decrypt(message).message return json.loads(token_string)
该方案需要执行额外磁盘IO操作,而加密响应内容已经存在于内存中,理想方案是全程在内存完成解析解密,无需落盘。
正确的纯内存实现方案
PGPy提供了PGPMessage.from_blob()类方法,专门用于解析内存中存储的字符串/字节格式PGP消息(同时支持ASCII装甲格式、二进制格式),直接返回可用于解密的PGPMessage对象,完全不需要文件IO操作。
修正后的可运行代码如下:
import json import pgpy def get_token_from_payload(encrypted_payload): privkey, _ = pgpy.PGPKey.from_file('private.key') # 直接解析内存中的ASCII装甲字符串为PGPMessage对象 message = pgpy.PGPMessage.from_blob(encrypted_payload) token_string = privkey.decrypt(message).message return json.loads(token_string)
*注意:最初实现版本中json.load为笔误,该方法仅支持读取文件对象,解析内存中的JSON字符串需要使用json.loads。
内容的提问来源于stack exchange,提问作者granitdev
相关产品推荐
相关产品推荐

