Install & Compatibility
Where this runs
tested against v0.6.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.162s · 36.6MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 4.4s · import 0.152s · 37MB
35MB installed
● package 35MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
PGPKey
✓ from pgpy.pgp import PGPKey
PGPMessage
✓ from pgpy.pgp import PGPMessage
PGPUID
✓ from pgpy.pgp import PGPUID
constants
✓ from pgpy import constants
Demonstrates generating a new PGP key, adding a User ID, optionally protecting the private key with a passphrase, encrypting a simple message, and then decrypting it. This covers the fundamental use cases for PGPy.
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!
pgpy --version
Debug
Known issues
breakingPython 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.fixUpgrade your Python environment to 3.5 or newer before upgrading to PGPy v0.6.0.
affects: <0.6.0
gotchaPassphrase 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.fixBe aware of encoding differences. For new keys and passphrases, UTF-8 is now the standard. You may need to specify encoding or re-protect older keys.
affects: <0.5.3
gotchaVersions of PGPy prior to v0.5.4 had compatibility breaks with Python 3.8 and newer, specifically related to importing ABCs from `collections`.fixUpgrade PGPy to v0.5.4 or a newer version to ensure full compatibility with Python 3.8 and above.
affects: <0.5.4 running on Python >=3.8
breakingVersion 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.fixUsers migrating from very old versions (pre-0.3.0) should consult the changelog for v0.3.0 and newer to adapt to the updated API for key generation, signatures, and message handling.
affects: <0.3.0
Errors
Common errors & fixes
AttributeError: module 'cryptography.utils' has no attribute 'register_interface'
This error occurs due to an incompatibility between `pgpy` and newer versions of its `cryptography` dependency, where a breaking change in `cryptography` removed the `register_interface` attribute.
fixDowngrade the `cryptography` library to a compatible version (e.g., `cryptography==37.0.4`) and then reinstall `pgpy` if necessary. You can do this with `pip install cryptography==37.0.4`.
ImportError: No module named pgpy
The `pgpy` package is either not installed in the active Python environment or the script is being executed with a different Python interpreter where `pgpy` is not present.
fixEnsure `pgpy` is installed for the correct Python interpreter by running `pip install pgpy`. If using a virtual environment, make sure it is activated.
ValueError: Expected: ASCII-armored PGP data
This error typically arises when attempting to load PGP data (key or message) using `PGPKey.from_blob()` or `PGPKey.from_file()` methods, but the input data is in a binary format or is malformed, and `pgpy` expects ASCII-armored (text-based) PGP data.
fixEnsure the input string or file content is a valid ASCII-armored PGP block, including the `-----BEGIN PGP ... BLOCK-----` headers and footers. If you are intentionally trying to load binary PGP data, `pgpy.PGPKey.from_file()` and `pgpy.PGPMessage.from_file()` can often handle both, but `from_blob` might be more particular, and the input itself must be correctly formatted binary PGP data.
pgpy.errors.PGPError: Key ... does not have the required usage flag EncryptStorage, EncryptCommunications
The PGP public key being used for encryption does not have the necessary 'Encrypt Communications' or 'Encrypt Storage' usage flags (KeyFlags) explicitly set, which is a requirement of the OpenPGP standard for encryption operations.
fixGenerate a new PGP key or subkey with the appropriate `KeyFlags.EncryptCommunications` and/or `KeyFlags.EncryptStorage` set. When creating keys, ensure you specify these flags for encryption purposes.
Upgrade
Version history
0.6.0latest on PyPI · released Nov 24, 2022
Audit
Dependencies
No dependency data recorded yet.