Skip to content

When to use this, and when not to

A short page, because most people arriving here should leave again.

The one-line test

Use this when the private key is somewhere your process cannot read it and the message is OpenPGP.

If the key is a file on disk, an environment variable, or anything else your program can load, you do not need this package. Use go-crypto — it will do the whole job, including the parts this package deliberately refuses.

Decision table

What you need Use
Decrypt an OpenPGP message with a key in a KMS, HSM or smartcard this, plus a provider
Assemble a certificate whose signing key is in a KMS this
Decrypt with a private key you can load go-crypto
Encrypt a message to someone go-crypto
Sign a message (not a certificate) go-crypto, or go/signing
Generate a key pair go-crypto, or your KMS
X25519 / X448 recipients go-crypto
Key revocation, expiry, web of trust go-crypto
A complete OpenPGP mail client not this, and not go-crypto alone

The two packages

Import Gives you
.../go/encryption SessionKey, DeriveKEK, ParsePacket, ParsePKESK, KDFParams, the key-service registry
.../go/encryption/certificate Assemble, Parse, ECDHPublicKey, RSAPublicKey, Fingerprint

Decryption is the common case and gets the shorter import. Assembly and certificate reading are a separate concern — and a separate package — because most callers publish a certificate once and decrypt for years.

The packet framing primitives (MPI encoding, packet headers, signature preimages) are not exported from either. They are the parts where a caller who gets it slightly wrong produces something that parses and silently misverifies, so they stay internal to the package that needs them.

The three modules

Module Owns Dependencies
go/encryption KDF, key unwrap, packet assembly, fingerprints standard library only
go/encryption-aws-kms DeriveSharedSecret and Sign against AWS KMS AWS SDK
sigillum message framing, body decryption, armour, the commands go-crypto

The split is the point. A consumer that only decrypts takes the first and a provider; it never inherits go-crypto or an AWS SDK to do arithmetic over public data. See why not go-crypto for the full argument, and the core and provider split for what lives where.

What "cannot read it" buys you

The property this whole design exists to provide is that no private key material exists in the process at any point. Assembling a certificate is two kms:Sign calls; opening a message addressed to it is one kms:DeriveSharedSecret. Everything else — the key derivation, the AES key unwrap, the checksum, the fingerprint — is arithmetic over values anyone is allowed to see.

That matters when the alternative is a long-lived private key on a laptop or in a CI secret. It matters much less if you were going to load a key from disk anyway, in which case the extra moving parts are a cost with no return.

Curve support

NIST P-256, P-384 and P-521, using OpenPGP public-key algorithm 18 with the RFC 6637 key derivation.

Not X25519 or X448 (algorithms 25 and 26): those use a different construction, and no major KMS offers them for key agreement — AWS KMS supports NIST curves and SM2 only. Choosing algorithm 18 was not a preference; it is the intersection of what OpenPGP defines and what a key service can hold. See why ECDH, not RSA.

Stability

Pre-1.0. The API may change, and the change that introduced crypto.Signer in place of a bespoke signing interface is an example of the kind of change to expect: motivated by an external standard rather than by internal preference, and made before rather than after the interface had users.