Skip to content

Repository files navigation

pg_crypto

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.

Build and install

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_config
CREATE EXTENSION pg_crypto;

pgcrypto compatibility

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.

Modern authenticated API

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 safety boundary

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.

Development

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)"

About

An extension for PostgreSQL to work with cryptographic primitives

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages