PGPy - Pretty Good Privacy for Python
PGPy is a Python library that implements Pretty Good Privacy (PGP) as described in RFC 4880. It provides capabilities for key generation, encryption, decryption, and signature management. The library is currently at version 0.6.0 and has an irregular release cadence, with major changes often accompanied by Python version requirement updates.
Warnings
- breaking Python 2.7 and 3.4 support was officially dropped in PGPy v0.6.0. Attempts to install or run PGPy v0.6.0+ on these Python versions will fail.
- gotcha Passphrase encoding for keys changed from Latin-1 to UTF-8 in v0.5.3. This may cause compatibility issues when importing keys generated with older PGPy versions or interacting with other PGP software that expects Latin-1.
- gotcha Versions of PGPy prior to v0.5.4 had compatibility breaks with Python 3.8 and newer, specifically related to importing ABCs from `collections`.
- breaking Version 0.3.0 introduced 'semi-significant API changes' that could break existing code. This included major updates to signature generation/verification and encryption/decryption APIs.
Install
-
pip install pgpy
Imports
- PGPKey
from pgpy.pgp import PGPKey
- PGPMessage
from pgpy.pgp import PGPMessage
- PGPUID
from pgpy.pgp import PGPUID
- constants
from pgpy import constants
Quickstart
import pgpy
from pgpy.constants import PubKeyAlgorithm, KeyFlags, HashAlgorithm, SymmetricKeyAlgorithm, CompressionAlgorithm
# 1. Generate a new RSA PGP key
key = pgpy.PGPKey.new(PubKeyAlgorithm.RSAEncryptOrSign, 4096)
# 2. Create a User ID
uid = pgpy.PGPUID.new('Test User', comment='example', email='test@example.com')
# 3. Add the User ID to the key, defining its capabilities
key.add_uid(uid,
usage={KeyFlags.Sign, KeyFlags.Encrypt},
hashes=[HashAlgorithm.SHA512, HashAlgorithm.SHA256],
ciphers=[SymmetricKeyAlgorithm.AES256, SymmetricKeyAlgorithm.AES192, SymmetricKeyAlgorithm.AES128],
compression=[CompressionAlgorithm.ZLIB, CompressionAlgorithm.BZ2, CompressionAlgorithm.ZIP, CompressionAlgorithm.Uncompressed])
# 4. (Optional) Protect the private key with a passphrase
passphrase = "my_secret_passphrase"
key.protect(passphrase, SymmetricKeyAlgorithm.AES256, HashAlgorithm.SHA256)
# 5. Create a PGP message
message_to_encrypt = pgpy.PGPMessage.new("This is a secret message that needs to be encrypted.")
# 6. Encrypt the message using the public key part of the generated key
encrypted_message = key.encrypt(message_to_encrypt)
# 7. Decrypt the message using the private key part
# If the key is protected, it must be unlocked first.
if key.is_protected:
with key.unlock(passphrase):
decrypted_message = key.decrypt(encrypted_message)
else:
decrypted_message = key.decrypt(encrypted_message)
print(f"Original message: {message_to_encrypt.message}")
print(f"Decrypted message: {decrypted_message.message}")
# You can also export the key to an armored string
# public_key_armor = str(key.pubkey)
# private_key_armor = str(key) # WARNING: Handle private keys with extreme care!