rpgp-py
Selected native Python bindings for rPGP,
exposed as the openpgp package.
Installation
pip install rpgp-py
Requires Python 3.10 or newer.
API layout
Exposed rPGP types live in the namespace that matches their upstream Rust module. The upstream documentation is therefore useful for the exposed names and their OpenPGP semantics, but this package is not a complete projection of every rPGP module or trait.
| Python namespace | Purpose |
|---|---|
openpgp.armor |
Native rPGP ASCII armor reader, writer, block types, and CRC status. |
openpgp.composed |
Transferable keys, messages, signatures, message builders, and key-generation builders. |
openpgp.packet |
Packet-shaped objects such as key packets, signatures, session-key packets, features, flags, and encrypted data packets. |
openpgp.types |
Public-parameter objects, S2K configuration, packet header versions, and shared type helpers. |
openpgp.crypto |
Crypto algorithm namespaces. |
openpgp.errors |
The native rPGP binding exception. |
openpgp.ser |
Native serialization helpers corresponding to rPGP's Serialize trait. |
openpgp.util |
Binding-specific helper functions built on top of the Rust-shaped API. |
Functionality
rpgp-py can:
- parse armored and binary public keys, secret keys, detached signatures, and OpenPGP messages,
- inspect transferable key details, users, subkeys, signatures, packet versions, key flags, features, public parameters, and S2K metadata,
- verify key bindings, signed messages, detached signatures, and cleartext signatures,
- build signed, compressed, password-encrypted, and recipient-encrypted messages,
- decrypt messages with secret keys, passwords, or caller-supplied session keys,
- generate modern OpenPGP key material, including v6 Ed25519/X25519 keys,
- use RFC 9580-era features exposed by rPGP, including SEIPD v2, OCB, and Argon2 S2K,
- parse and serialize individual native packet values and verify individual key and subkey signature packets,
- use native armor, error, serialization, value-type, and algorithm bindings,
- use convenience helpers from
openpgp.utilwhen you want one-call signing or encryption.
Usage
Parse and inspect keys
from openpgp.composed import SignedPublicKey, SignedSecretKey
public_key, headers = SignedPublicKey.from_armor(public_key_armor)
secret_key, _ = SignedSecretKey.from_armor(secret_key_armor)
public_key.verify_bindings()
secret_key.verify_bindings()
assert secret_key.to_public_key().fingerprint == public_key.fingerprint
assert public_key.primary_key.fingerprint == public_key.fingerprint
assert public_key.details.users[0].id == public_key.user_ids[0]
for signed_subkey in public_key.public_subkeys:
print(signed_subkey.key.fingerprint)
print(signed_subkey.signatures[0].typ())
params = public_key.public_params
print(params.kind)
Sign and verify a message
from openpgp.composed import Message, MessageBuilder
armored = (
MessageBuilder.from_bytes("message.txt", b"hello world")
.sign(secret_key, None, "sha256")
.to_armored_string()
)
message, _ = Message.from_armor(armored)
signature = message.verify(public_key)
assert signature.hash_alg() == "sha256"
assert message.as_data_string() == "hello world"
Create and verify a detached signature
import os
from openpgp.composed import DetachedSignature
class SecureRandom:
def randbytes(self, n: int) -> bytes:
return os.urandom(n)
signature = DetachedSignature.sign_binary_data(
SecureRandom(),
secret_key,
None,
"sha512",
b"payload",
)
signature.verify(public_key, b"payload")
assert signature.signature.hash_alg() == "sha512"
Work with cleartext signatures
from openpgp.composed import CleartextSignedMessage
cleartext = CleartextSignedMessage.sign("hello\n-world\n", secret_key)
armored = cleartext.to_armored()
reparsed, _ = CleartextSignedMessage.from_armor(armored)
reparsed.verify(public_key)
assert reparsed.signed_text() == "hello\r\n-world\r\n"
assert reparsed.signature_count() == 1
Encrypt to a recipient
from openpgp.composed import Message, MessageBuilder
armored = (
MessageBuilder.from_bytes("secret.txt", b"secret payload")
.seipd_v2("aes256", "ocb")
.encrypt_to_key(public_key)
.to_armored_string()
)
message, _ = Message.from_armor(armored)
decrypted = message.decrypt(None, secret_key)
assert decrypted.as_data_vec() == b"secret payload"
For anonymous recipients or multi-recipient messages, keep chaining recipient operations:
armored = (
MessageBuilder.from_bytes("shared.txt", b"shared payload")
.seipd_v2("aes256", "ocb")
.encrypt_to_key_anonymous(first_public_key)
.encrypt_to_key(second_public_key)
.to_armored_string()
)
Encrypt with a password
from openpgp.composed import Message, MessageBuilder
from openpgp.types import StringToKey
armored = (
MessageBuilder.from_bytes("", b"password protected")
.seipd_v2("aes256", "ocb")
.encrypt_with_password(StringToKey.argon2(1, 4, 21), "hunter2")
.to_armored_string()
)
message, _ = Message.from_armor(armored)
decrypted = message.decrypt_with_password("hunter2")
assert decrypted.as_data_string() == "password protected"
Inspect encrypted packets and use a session key
from openpgp.composed import Message, MessageBuilder
session_key = bytes(range(16))
message_bytes = (
MessageBuilder.from_bytes("", b"packet payload")
.seipd_v2("aes128", "ocb")
.set_session_key(session_key)
.encrypt_to_key(public_key)
.to_vec()
)
message = Message.from_bytes(message_bytes)
pkesk = message.public_key_encrypted_session_key_packets()[0]
edata = message.encrypted_data_packet()
assert pkesk.recipient_is_anonymous is False
assert edata.kind == "seipd-v2"
assert message.decrypt_with_session_key(session_key).as_data_vec() == b"packet payload"
Generate key material
from openpgp.composed import (
EncryptionCaps,
KeyType,
SecretKeyParamsBuilder,
SubkeyParamsBuilder,
)
from openpgp.types import PacketHeaderVersion, S2kParams, StringToKey
secret_key = (
SecretKeyParamsBuilder()
.version(6)
.key_type(KeyType.ed25519())
.packet_version(PacketHeaderVersion.new())
.can_certify(True)
.can_sign(True)
.feature_seipd_v2(True)
.primary_user_id("Me <me@example.com>")
.passphrase("hunter2")
.s2k(S2kParams.aead("aes256", "ocb", StringToKey.argon2(3, 4, 16)))
.subkey(
SubkeyParamsBuilder()
.version(6)
.key_type(KeyType.x25519())
.packet_version(PacketHeaderVersion.new())
.can_encrypt(EncryptionCaps.all())
.build()
)
.generate()
)
public_key = secret_key.to_public_key()
secret_key.verify_bindings()
public_key.verify_bindings()
assert public_key.public_key_algorithm == "ed25519"
assert public_key.public_params.kind == "ed25519"
Use convenience helpers
Use openpgp.util when you want compact helpers instead of manually building a
message pipeline:
from openpgp.util import encrypt_message_to_recipient, sign_message
signed = sign_message(b"hello", secret_key)
encrypted = encrypt_message_to_recipient(b"secret", public_key)
The helper namespace also includes multi-signer, cleartext, byte-output, multi-recipient, password-encryption, and session-key helpers.
Reference documentation
Versioning
rpgp-py follows the major and minor version of the underlying pgp crate. The
patch version is incremented for Python-facing API changes and Rust-core build
updates such as dependency updates or bug fixes.
Acknowledgements
Thanks to the rPGP contributors and
maintainers for the Rust OpenPGP implementation that powers this package.
License
This repository is distributed under the MIT License.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rpgp_py-0.20.0.tar.gz.
File metadata
- Download URL: rpgp_py-0.20.0.tar.gz
- Upload date:
- Size: 144.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a072023dfd034f914266e34b91d54b415565a12a2a177c23e720714c1ebf8a1
|
|
| MD5 |
cc2f35471ba29c7400c0f2b58f26495c
|
|
| BLAKE2b-256 |
d107761c1c03da215f1db06f63af56a10f700e7158b1676669324b236cbef935
|
File details
Details for the file rpgp_py-0.20.0-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: rpgp_py-0.20.0-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 3.1 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
278d002db1a91a709f5fdc423e06adba0852e1ed2ad363ecb1b70decc9e80516
|
|
| MD5 |
c725bcf7b9b77c47ceb1641597b4b32b
|
|
| BLAKE2b-256 |
bf3f868a9f090ecec6ec26d52522aab0f33e25184ec48a4ce260cf834fda48be
|
File details
Details for the file rpgp_py-0.20.0-cp310-abi3-win32.whl.
File metadata
- Download URL: rpgp_py-0.20.0-cp310-abi3-win32.whl
- Upload date:
- Size: 2.8 MB
- Tags: CPython 3.10+, Windows x86
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4802be4265103aa3ac5ac7882ac7388fe4b3bd3ad2257500f6ab5a8f2879637
|
|
| MD5 |
e8807a2b22ddf8ca76923da495d0dc50
|
|
| BLAKE2b-256 |
bf7cad594a2810bb7093958d0ca9a4693db773c775f833510435e3a49ab33274
|
File details
Details for the file rpgp_py-0.20.0-cp310-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: rpgp_py-0.20.0-cp310-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 3.6 MB
- Tags: CPython 3.10+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
659475b9ba64cc42596e2bfa953f9cb7fd271486b2e2a957d3a7660baa6712d5
|
|
| MD5 |
818692907cd792ed8deac3375ccf3fc2
|
|
| BLAKE2b-256 |
f2027f953e4c2b681c917f1d27aa204042b9552a9eb674d7cefa0233b2302eac
|
File details
Details for the file rpgp_py-0.20.0-cp310-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: rpgp_py-0.20.0-cp310-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 3.5 MB
- Tags: CPython 3.10+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95881d16420949c6b893bff60276aa5da0683ae86e4cab98506b54f7b293c8f2
|
|
| MD5 |
6fa4aad3921cc8cdeb540c00328c3466
|
|
| BLAKE2b-256 |
8ca1b122189c65bce7bdd60d1e2861b663c32d583f6c259c1ddd1da56d0aee50
|
File details
Details for the file rpgp_py-0.20.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: rpgp_py-0.20.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 3.3 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
499c28ba70b2e2da214e9463369a6d929062e8e7037447b6d45a9d2663f3ba43
|
|
| MD5 |
908bb39946072faa1665c6ca2e943216
|
|
| BLAKE2b-256 |
e6f9d53041547713dfec33f035d029e15b4127c4d02dcab8fbeb4af8795fd16e
|
File details
Details for the file rpgp_py-0.20.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: rpgp_py-0.20.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 3.3 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fca326cbcbe0102bba1c2628ccaee2d75229fe50195c90bb646d79a55a330b0e
|
|
| MD5 |
30270521adbf6cc43fbdff135bd89292
|
|
| BLAKE2b-256 |
4e5a480757bf4495abd7649c35580aa59ada149c57ae386349ad8eab08d8ad6d
|
File details
Details for the file rpgp_py-0.20.0-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: rpgp_py-0.20.0-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.0 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63286e891a0910f9d2e407b94cb21b274dcdc5d3f1e60d101b884667ce0a3c70
|
|
| MD5 |
930e2c36d09ea697da22c0bbda2b3bdf
|
|
| BLAKE2b-256 |
6cbd45bbe117b7a56e1ab8cd6742becaadffc879f460be6a89d16d0fd9765ecc
|
File details
Details for the file rpgp_py-0.20.0-cp310-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: rpgp_py-0.20.0-cp310-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 3.1 MB
- Tags: CPython 3.10+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
618354b938c629661f9a19e290d06dbd41c20ca908cf47058c25aa629c7ccb82
|
|
| MD5 |
a3008138d544a4871eb8e80179bec0b3
|
|
| BLAKE2b-256 |
0d10e14898866810360e5394d10997660500e080224a57b8df1a95a9b30d54d7
|