如何用Python3的PGPY加密消息?遇密钥权限报错求助
嘿,我看你用PGPy加密明文时遇到了权限错误,咱们一步步来解决它:
你的代码
import pgpy key,_ = pgpy.PGPKey.from_file('public_key.asc') data = "This is simple message" msg = pgpy.PGPMessage.new(data, cleartext=True) encrypted_message = key.encrypt(msg) print (encrypted_message)
报错信息
Traceback (most recent call last):
File "pgp_encrypt.py", line 8, in
encrypted_message = key.encrypt(msg)
File "/home//.local/lib/python3.8/site-packages/pgpy/decorators.py", line 125, in _action
with self.usage(key, kwargs.get('user', None)) as _key:
File "/usr/lib/python3.8/contextlib.py", line 113, in enter
return next(self.gen)
File "/home//.local/lib/python3.8/site-packages/pgpy/decorators.py", line 96, in usage
raise PGPError("Key {keyid:s} does not have the required usage flag {flags:s}".format(**em))
pgpy.errors.PGPError: Key 2F0B2A386761A2B8 does not have the required usage flag EncryptStorage, EncryptCommunications
问题根源
这个错误说得很直白:你使用的公钥没有启用加密相关的权限标志(EncryptStorage或EncryptCommunications)。PGP密钥是分用途的,有的只能用来签名,有的负责加密,你现在用的这个密钥明显是签名专用的,没法执行加密操作。
解决办法
1. 先确认现有密钥的用途
先跑一段代码验证这个密钥的权限范围:
import pgpy key, _ = pgpy.PGPKey.from_file('public_key.asc') print(key.pubkey.usages)
如果输出里找不到EncryptStorage或EncryptCommunications,那实锤了——这个密钥确实不能用来加密。
2. 生成带加密权限的新密钥对
要是你是自己生成的密钥,重新生成时记得加上加密权限。用PGPy生成的话可以这么写:
import pgpy from pgpy.constants import PubKeyAlgorithm, KeyFlags, HashAlgorithm, SymmetricKeyAlgorithm, CompressionAlgorithm # 创建2048位RSA密钥对 key = pgpy.PGPKey.new(PubKeyAlgorithm.RSAEncryptOrSign, 2048) # 设置用户ID和密钥用途:同时启用加密和签名,可按需调整 uid = pgpy.PGPUID.new('Your Name', email='your@email.com') key.add_uid(uid, usage={KeyFlags.EncryptCommunications, KeyFlags.EncryptStorage, KeyFlags.Sign}, hashes=[HashAlgorithm.SHA256], ciphers=[SymmetricKeyAlgorithm.AES256], compression=[CompressionAlgorithm.ZLIB]) # 导出公钥和私钥到文件 with open('public_encrypt_key.asc', 'w') as f: f.write(str(key.pubkey)) with open('private_key.asc', 'w') as f: f.write(str(key))
用这个新生成的公钥加密,就不会再触发权限错误了。
3. 检查是否有加密专用的子密钥
很多PGP工具会生成「主密钥(负责签名)+ 子密钥(负责加密)」的结构。如果你手里的密钥是这种情况,得找到对应的加密子密钥来用,而不是主密钥。可以用这段代码遍历查找:
import pgpy from pgpy.constants import KeyFlags key, _ = pgpy.PGPKey.from_file('public_key.asc') # 遍历子密钥,找到支持加密的那个 encrypt_subkey = None for subkey in key.subkeys: if (KeyFlags.EncryptCommunications in subkey.pubkey.usages or KeyFlags.EncryptStorage in subkey.pubkey.usages): encrypt_subkey = subkey break if encrypt_subkey: msg = pgpy.PGPMessage.new("This is simple message", cleartext=True) encrypted_msg = encrypt_subkey.encrypt(msg) print(encrypted_msg) else: print("没找到支持加密的子密钥,要么换密钥要么重新生成吧!")
这样应该就能搞定你的问题啦~
内容的提问来源于stack exchange,提问作者krishna reddy

