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).
High-level OpenPGP operations for encryption, signing, and key management.
var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
var PublicKeyType = "PGP PUBLIC KEY BLOCK"
var SignatureType = "PGP SIGNATURE"// 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// 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)// 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)ASCII Armor encoding (similar to PEM with checksums).
var ArmorCorrupt error = errors.StructuralError("armor invalid")// 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)// Block represents an OpenPGP armored structure.
type Block struct {
Type string
Header map[string]string
Body io.Reader
// contains unexported fields
}Clear-text signatures (RFC 4880).
// 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)// 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)ElGamal encryption for OpenPGP. Deprecated - compatibility and security issues.
// 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)// 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
}Common error types for OpenPGP.
var ErrKeyIncorrect error = keyIncorrectError(0)
var ErrKeyRevoked error = keyRevokedError(0)
var ErrUnknownIssuer error = unknownIssuerError(0)// 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() stringLow-level OpenPGP packet parsing and serialization (RFC 4880).
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// 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// 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.StreamOpenPGP string-to-key transforms (RFC 4880).
// 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)// Config contains S2K configuration.
type Config struct {
Hash crypto.Hash
S2KCount int
}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)
}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)
}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)
}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))
}Since OpenPGP packages are deprecated, consider these alternatives:
For new projects:
For existing projects:
Specific use cases: