pg_crypto is a pure-Rust PostgreSQL extension that combines the familiar
pgcrypto SQL surface with authenticated modern cryptography.
- RustCrypto provides hashes, HMAC, AES/Blowfish raw modes, and compatibility password formats.
- Sequoia provides RFC 4880 OpenPGP encryption, compression, key parsing, and ASCII armor.
- dryoc provides the CSPRNG, Argon2id, XChaCha20-Poly1305, secretbox, sealed box, Ed25519, and X25519.
The extension performs no network access and has no OpenSSL dependency.
pg_crypto supports PostgreSQL 14–18, Rust 1.96+, and cargo-pgrx 0.19.2.
cargo install cargo-pgrx --version 0.19.2 --locked
cargo pgrx init --pg18=/path/to/pg_config
./install.sh --pg-config /path/to/pg_configCREATE EXTENSION pg_crypto;SELECT encode(digest('hello', 'sha256'), 'hex');
SELECT hmac('message', 'secret', 'sha512');
SELECT crypt('password', gen_salt('bf', 12));
SELECT decrypt_iv(
encrypt_iv('data'::bytea, 'key'::bytea, 'iv'::bytea, 'aes-cbc'),
'key'::bytea, 'iv'::bytea, 'aes-cbc'
);
SELECT pgp_sym_decrypt(
pgp_sym_encrypt('private', 'passphrase', 'cipher-algo=aes256'),
'passphrase'
);
SELECT armor(
decode('000102ff', 'hex'),
ARRAY['Comment'], ARRAY['generated by pg_crypto']
);The compatibility surface includes digest, hmac, crypt, gen_salt, raw
encrypt/decrypt and IV variants, symmetric and public-key OpenPGP,
armor/dearmor, pgp_key_id, pgp_armor_headers, random bytes, UUID v4,
and fips_mode.
Raw AES selects AES-128, AES-192, or AES-256 from the supplied key length and
zero-pads short keys, matching pgcrypto. Historical rijndael* and
blowfish* aliases are accepted. CFB is unpadded because it is a stream mode.
WITH key AS (SELECT gen_random_bytes(32) AS value)
SELECT xchacha20poly1305_decrypt(
xchacha20poly1305_encrypt('secret'::bytea, value, 'context'::bytea),
value,
'context'::bytea
) FROM key;
SELECT argon2id_hash('a long unique password');
SELECT secretbox('secret'::bytea, gen_random_bytes(32));Modern encryption functions return self-contained bytea envelopes and
authenticate ciphertext and associated data. Raw CBC, CFB, and ECB functions
exist only for compatibility; new applications should use
XChaCha20-Poly1305.
OpenPGP encryption always emits integrity-protected RFC 4880 messages;
disable-mdc=1 is rejected. ignore-cipher-failure is accepted for valid
messages but does not recover historical malformed ciphertext produced when an
older pgcrypto/OpenSSL cipher operation failed.
See the SQL API, security model, and support matrix.
cargo fmt --all -- --check
cargo clippy --all-targets --no-default-features --features pg18 -- \
-D warnings -W clippy::pedantic
./ci/test-upgrade.sh
./ci/test-extension.sh "$(cargo pgrx info pg-config 18)"
./ci/test-gpg-interop.sh "$(cargo pgrx info pg-config 18)"