or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

acme.mdencryption.mdhashing.mdindex.mdnacl.mdopenpgp.mdpublic-key.mdssh.mdutilities.md
tile.json

openpgp.mddocs/

OpenPGP Implementation

DEPRECATION NOTICE: All OpenPGP packages are deprecated and unmaintained except for security fixes. Consider using alternative solutions for new projects.

The OpenPGP packages provide high-level operations for encryption, signing, and key management using the OpenPGP standard (RFC 4880).

Package: golang.org/x/crypto/openpgp

High-level OpenPGP operations for encryption, signing, and key management.

Variables

var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
var PublicKeyType = "PGP PUBLIC KEY BLOCK"
var SignatureType = "PGP SIGNATURE"

Functions

// Encrypt encrypts a message to a number of recipients and, optionally, signs it.
func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error)

// SymmetricallyEncrypt encrypts a message with a passphrase.
func SymmetricallyEncrypt(ciphertext io.Writer, passphrase []byte, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error)

// Sign signs a message.
func Sign(output io.Writer, signed *Entity, hints *FileHints, config *packet.Config) (input io.WriteCloser, err error)

// DetachSign creates a detached signature.
func DetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error

// DetachSignText signs canonicalized text data.
func DetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error

// ArmoredDetachSign creates an armored detached signature.
func ArmoredDetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) (err error)

// ArmoredDetachSignText creates an armored detached signature for text.
func ArmoredDetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error

// NewCanonicalTextHash returns a hash suitable for hashing text.
func NewCanonicalTextHash(h hash.Hash) hash.Hash

Types

// Entity represents an OpenPGP key (public or private).
type Entity struct {
    // PrimaryKey is the main key.
    PrimaryKey *packet.PublicKey

    // PrivateKey is the private part (nil for public-only entities).
    PrivateKey *packet.PrivateKey

    // Identities contains user IDs and self-signatures.
    Identities map[string]*Identity

    // Revocations is a list of revocation signatures.
    Revocations []*packet.Signature

    // Subkeys contains additional keys.
    Subkeys []Subkey
}

// NewEntity creates a new entity.
func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error)

// ReadEntity reads a single entity from a packet reader.
func ReadEntity(packets *packet.Reader) (*Entity, error)

// Serialize writes the entity to w (public parts only).
func (e *Entity) Serialize(w io.Writer) error

// SerializePrivate writes the entity including private keys.
func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error)

// SignIdentity signs an identity with another entity.
func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error

// EntityList is a list of entities.
type EntityList []*Entity

// ReadKeyRing reads a keyring from a Reader.
func ReadKeyRing(r io.Reader) (el EntityList, err error)

// ReadArmoredKeyRing reads an ASCII-armored keyring.
func ReadArmoredKeyRing(r io.Reader) (EntityList, error)

// DecryptionKeys returns all keys capable of decrypting.
func (el EntityList) DecryptionKeys() (keys []Key)

// KeysById returns keys with the given ID.
func (el EntityList) KeysById(id uint64) (keys []Key)

// KeysByIdUsage returns keys with the given ID and usage flags.
func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key)

// Identity represents a user identity.
type Identity struct {
    Name          string
    UserId        *packet.UserId
    SelfSignature *packet.Signature
    Signatures    []*packet.Signature
}

// Subkey represents an additional encryption or signing key.
type Subkey struct {
    PublicKey  *packet.PublicKey
    PrivateKey *packet.PrivateKey
    Sig        *packet.Signature
}

// Key represents a specific public key in an entity.
type Key struct {
    Entity        *Entity
    PublicKey     *packet.PublicKey
    PrivateKey    *packet.PrivateKey
    SelfSignature *packet.Signature
}

// KeyRing is an interface for accessing keys.
type KeyRing interface {
    KeysById(id uint64) []Key
    KeysByIdUsage(id uint64, requiredUsage byte) []Key
    DecryptionKeys() []Key
}

// FileHints contains metadata about encrypted files.
type FileHints struct {
    IsBinary bool
    FileName string
    ModTime  time.Time
}

// MessageDetails contains information about a processed message.
type MessageDetails struct {
    IsEncrypted              bool
    EncryptedToKeyIds        []uint64
    IsSymmetricallyEncrypted bool
    DecryptedWith            Key
    IsSigned                 bool
    SignedByKeyId            uint64
    SignedBy                 *Key
    LiteralData              *packet.LiteralData
    UnverifiedBody           io.Reader
    SignatureError           error
    Signature                *packet.Signature
    SignatureV3              *packet.SignatureV3
    // contains unexported fields
}

// ReadMessage reads an OpenPGP message.
func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error)

// PromptFunction is a callback for passphrase/key decryption.
type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)

Signature Verification

// CheckDetachedSignature verifies a detached signature.
func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error)

// CheckArmoredDetachedSignature verifies an armored detached signature.
func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error)

Package: golang.org/x/crypto/openpgp/armor

ASCII Armor encoding (similar to PEM with checksums).

Variables

var ArmorCorrupt error = errors.StructuralError("armor invalid")

Functions

// Encode creates a WriteCloser for writing armored data.
func Encode(out io.Writer, blockType string, headers map[string]string) (w io.WriteCloser, err error)

// Decode reads an armored block.
func Decode(in io.Reader) (p *Block, err error)

Types

// Block represents an OpenPGP armored structure.
type Block struct {
    Type   string
    Header map[string]string
    Body   io.Reader
    // contains unexported fields
}

Package: golang.org/x/crypto/openpgp/clearsign

Clear-text signatures (RFC 4880).

Functions

// Encode returns a WriteCloser for clear-signing a message.
func Encode(w io.Writer, privateKey *packet.PrivateKey, config *packet.Config) (plaintext io.WriteCloser, err error)

// EncodeMulti returns a WriteCloser for clear-signing with multiple keys.
func EncodeMulti(w io.Writer, privateKeys []*packet.PrivateKey, config *packet.Config) (plaintext io.WriteCloser, err error)

Types

// Block represents a clear-signed message.
type Block struct {
    Headers          textproto.MIMEHeader
    Plaintext        []byte
    Bytes            []byte
    ArmoredSignature *armor.Block
}

// Decode finds and decodes a clear-signed message.
func Decode(data []byte) (b *Block, rest []byte)

Package: golang.org/x/crypto/openpgp/elgamal

ElGamal encryption for OpenPGP. Deprecated - compatibility and security issues.

Functions

// Encrypt encrypts a message to the given public key.
func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err error)

// Decrypt decrypts a message encrypted with Encrypt.
func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error)

Types

// PublicKey represents an ElGamal public key.
type PublicKey struct {
    G, P, Y *big.Int
}

// PrivateKey represents an ElGamal private key.
type PrivateKey struct {
    PublicKey
    X *big.Int
}

Package: golang.org/x/crypto/openpgp/errors

Common error types for OpenPGP.

Variables

var ErrKeyIncorrect error = keyIncorrectError(0)
var ErrKeyRevoked error = keyRevokedError(0)
var ErrUnknownIssuer error = unknownIssuerError(0)

Types

// StructuralError indicates syntactically invalid OpenPGP data.
type StructuralError string

func (s StructuralError) Error() string

// UnsupportedError indicates an unimplemented OpenPGP feature.
type UnsupportedError string

func (s UnsupportedError) Error() string

// InvalidArgumentError indicates an invalid caller argument.
type InvalidArgumentError string

func (i InvalidArgumentError) Error() string

// SignatureError indicates signature validation failure.
type SignatureError string

func (b SignatureError) Error() string

// UnknownPacketTypeError indicates an unknown packet type.
type UnknownPacketTypeError uint8

func (upte UnknownPacketTypeError) Error() string

Package: golang.org/x/crypto/openpgp/packet

Low-level OpenPGP packet parsing and serialization (RFC 4880).

Constants

const (
    NoCompression      = flate.NoCompression
    BestSpeed          = flate.BestSpeed
    BestCompression    = flate.BestCompression
    DefaultCompression = flate.DefaultCompression
)

const (
    SigTypeBinary            SignatureType = 0
    SigTypeText                            = 1
    SigTypeGenericCert                     = 0x10
    SigTypePersonaCert                     = 0x11
    SigTypeCasualCert                      = 0x12
    SigTypePositiveCert                    = 0x13
    SigTypeSubkeyBinding                   = 0x18
    SigTypePrimaryKeyBinding               = 0x19
    SigTypeDirectSignature                 = 0x1F
    SigTypeKeyRevocation                   = 0x20
    SigTypeSubkeyRevocation                = 0x28
)

const (
    KeyFlagCertify = 1 << iota
    KeyFlagSign
    KeyFlagEncryptCommunications
    KeyFlagEncryptStorage
)

const UserAttrImageSubpacket = 1

Types

// Config contains configuration parameters.
type Config struct {
    Rand                   io.Reader
    DefaultHash            crypto.Hash
    DefaultCipher          CipherFunction
    Time                   func() time.Time
    DefaultCompressionAlgo CompressionAlgo
    CompressionConfig      *CompressionConfig
    S2KCount               int
    RSABits                int
}

// CipherFunction is a block cipher identifier.
type CipherFunction uint8

const (
    Cipher3DES   CipherFunction = 2
    CipherCAST5  CipherFunction = 3
    CipherAES128 CipherFunction = 7
    CipherAES192 CipherFunction = 8
    CipherAES256 CipherFunction = 9
)

func (cipher CipherFunction) KeySize() int

// CompressionAlgo is a compression algorithm identifier.
type CompressionAlgo uint8

const (
    CompressionNone CompressionAlgo = 0
    CompressionZIP  CompressionAlgo = 1
    CompressionZLIB CompressionAlgo = 2
)

// CompressionConfig contains compressor configuration.
type CompressionConfig struct {
    Level int
}

// SignatureType represents the type of an OpenPGP signature.
type SignatureType uint8

Functions

// Read reads a single OpenPGP packet.
func Read(r io.Reader) (p Packet, err error)

// SerializeLiteral serializes literal data.
func SerializeLiteral(w io.WriteCloser, isBinary bool, fileName string, time uint32) (plaintext io.WriteCloser, err error)

// SerializeCompressed serializes compressed data.
func SerializeCompressed(w io.WriteCloser, algo CompressionAlgo, cc *CompressionConfig) (literaldata io.WriteCloser, err error)

// SerializeSymmetricallyEncrypted serializes symmetrically encrypted data.
func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, key []byte, config *Config) (contents io.WriteCloser, err error)

// SerializeSymmetricKeyEncrypted serializes a symmetric key packet.
func SerializeSymmetricKeyEncrypted(w io.Writer, passphrase []byte, config *Config) (key []byte, err error)

// SerializeEncryptedKey serializes an encrypted key packet.
func SerializeEncryptedKey(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, key []byte, config *Config) error

// NewOCFBEncrypter creates an OpenPGP CFB encrypter.
func NewOCFBEncrypter(block cipher.Block, randData []byte, resync OCFBResyncOption) (cipher.Stream, []byte)

// NewOCFBDecrypter creates an OpenPGP CFB decrypter.
func NewOCFBDecrypter(block cipher.Block, prefix []byte, resync OCFBResyncOption) cipher.Stream

Package: golang.org/x/crypto/openpgp/s2k

OpenPGP string-to-key transforms (RFC 4880).

Functions

// Simple performs simple S2K.
func Simple(out []byte, h hash.Hash, in []byte)

// Salted performs salted S2K.
func Salted(out []byte, h hash.Hash, in []byte, salt []byte)

// Iterated performs iterated and salted S2K.
func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int)

// Parse parses an S2K specification.
func Parse(r io.Reader) (f func(out, in []byte), err error)

// Serialize serializes an S2K descriptor.
func Serialize(w io.Writer, key []byte, rand io.Reader, passphrase []byte, c *Config) error

// HashIdToHash converts an OpenPGP hash ID to crypto.Hash.
func HashIdToHash(id byte) (h crypto.Hash, ok bool)

// HashToHashId converts crypto.Hash to OpenPGP hash ID.
func HashToHashId(h crypto.Hash) (id byte, ok bool)

// HashIdToString converts hash ID to name.
func HashIdToString(id byte) (name string, ok bool)

Types

// Config contains S2K configuration.
type Config struct {
    Hash     crypto.Hash
    S2KCount int
}

Usage Examples

Encrypt and Sign

package main

import (
    "bytes"
    "io"
    "log"
    "golang.org/x/crypto/openpgp"
)

func main() {
    // Create entity (key pair)
    entity, err := openpgp.NewEntity("Name", "Comment", "email@example.com", nil)
    if err != nil {
        log.Fatal(err)
    }

    // Encrypt and sign a message
    var buf bytes.Buffer
    plaintext, err := openpgp.Encrypt(&buf, []*openpgp.Entity{entity}, entity, nil, nil)
    if err != nil {
        log.Fatal(err)
    }

    message := []byte("Secret message")
    plaintext.Write(message)
    plaintext.Close()

    // Decrypt and verify
    entityList := openpgp.EntityList{entity}
    md, err := openpgp.ReadMessage(&buf, entityList, nil, nil)
    if err != nil {
        log.Fatal(err)
    }

    decrypted, _ := io.ReadAll(md.UnverifiedBody)
    log.Printf("Decrypted: %s", decrypted)
    log.Printf("Signed by: %v", md.SignedBy != nil)
}

Symmetric Encryption

package main

import (
    "bytes"
    "io"
    "log"
    "golang.org/x/crypto/openpgp"
)

func main() {
    passphrase := []byte("secret-passphrase")
    message := []byte("Secret message")

    // Encrypt with passphrase
    var encrypted bytes.Buffer
    plaintext, _ := openpgp.SymmetricallyEncrypt(&encrypted, passphrase, nil, nil)
    plaintext.Write(message)
    plaintext.Close()

    // Decrypt with passphrase
    prompt := func(keys []openpgp.Key, symmetric bool) ([]byte, error) {
        return passphrase, nil
    }

    md, _ := openpgp.ReadMessage(&encrypted, nil, prompt, nil)
    decrypted, _ := io.ReadAll(md.UnverifiedBody)
    log.Printf("Decrypted: %s", decrypted)
}

Detached Signature

package main

import (
    "bytes"
    "log"
    "golang.org/x/crypto/openpgp"
)

func main() {
    entity, _ := openpgp.NewEntity("Name", "Comment", "email@example.com", nil)
    message := bytes.NewReader([]byte("Message to sign"))

    // Create detached signature
    var signature bytes.Buffer
    err := openpgp.DetachSign(&signature, entity, message, nil)
    if err != nil {
        log.Fatal(err)
    }

    // Verify detached signature
    message.Seek(0, 0)
    keyring := openpgp.EntityList{entity}
    signer, err := openpgp.CheckDetachedSignature(keyring, message, &signature)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Signed by: %v", signer.Identities)
}

Armored Output

package main

import (
    "bytes"
    "io"
    "log"
    "golang.org/x/crypto/openpgp"
    "golang.org/x/crypto/openpgp/armor"
)

func main() {
    entity, _ := openpgp.NewEntity("Name", "", "email@example.com", nil)

    // Armor public key
    var buf bytes.Buffer
    w, _ := armor.Encode(&buf, openpgp.PublicKeyType, nil)
    entity.Serialize(w)
    w.Close()

    log.Printf("Armored public key:\n%s", buf.String())

    // Read armored key
    block, _ := armor.Decode(&buf)
    if block.Type != openpgp.PublicKeyType {
        log.Fatal("Not a public key")
    }

    keys, _ := openpgp.ReadKeyRing(block.Body)
    log.Printf("Read %d keys", len(keys))
}

Migration Recommendations

Since OpenPGP packages are deprecated, consider these alternatives:

  1. For new projects:

    • Use modern alternatives like age (github.com/FiloSottile/age)
    • Use NaCl/libsodium bindings for simpler use cases
    • Use cms package for S/MIME (standard library)
  2. For existing projects:

    • Continue using for compatibility with existing systems
    • Plan migration to modern alternatives
    • Monitor security advisories
  3. Specific use cases:

    • File encryption: Use age or ChaCha20-Poly1305 directly
    • Email encryption: Consider alternative standards
    • Code signing: Use standard crypto/x509 certificates

Security Notes

  1. Deprecation: Package is unmaintained except for critical security fixes
  2. Algorithm strength: Some default algorithms (3DES, SHA-1) are weak
  3. Key management: OpenPGP key management is complex and error-prone
  4. Forward secrecy: OpenPGP does not provide forward secrecy
  5. Metadata leakage: OpenPGP exposes metadata like key IDs and timestamps