envelope

package
v1.25.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 19, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package envelope implements hybrid envelope encryption for efficient encryption of large data sets using a combination of symmetric and asymmetric cryptography.

Envelope encryption (also known as hybrid encryption) is a cryptographic technique that combines the speed of symmetric encryption with the key distribution benefits of asymmetric encryption. It's the recommended approach for encrypting large amounts of data or when you need to encrypt for multiple recipients.

How envelope encryption works:

  1. Generate a random symmetric encryption key (Data Encryption Key - DEK)
  2. Encrypt the actual data with the DEK using AES-GCM
  3. Encrypt the DEK with the recipient's public key (Key Encryption Key - KEK)
  4. Return both the encrypted data and the encrypted DEK

Advantages:

  • Efficient for large data (no size limitations)
  • Can encrypt for multiple recipients by encrypting DEK with each recipient's key
  • Provides perfect forward secrecy when using ephemeral keys
  • Scales well with data size (only DEK encryption time scales with recipients)

Security properties:

  • Data confidentiality through AES-GCM symmetric encryption
  • Key confidentiality through asymmetric encryption of the DEK
  • Data integrity and authenticity through AES-GCM authentication
  • Fresh DEK for each encryption operation

Use cases:

  • Encrypting files larger than RSA key size limits
  • Multi-recipient encryption scenarios
  • Cloud storage encryption
  • Secure messaging systems
  • Database field encryption

Package envelope — file external.go.

External wrapping support: standards-conformant RFC 5652 CMS EnvelopedData where the recipient's key-encryption key lives in an external service (HSM, KMS, smartcard, REST API). gopki handles the ASN.1 marshalling; the caller supplies the wrap/unwrap operations through ExternalWrapper.

EncryptWithExternalWrap deliberately returns DER-encoded CMS bytes (`[]byte`), NOT *encryption.EncryptedData. The latter is gopki's existing JSON-wrapped non-standard container produced by EncodeToCMS; that format is incompatible with the single-layer CMS this API produces.

Package envelope — file external_asn1.go.

Private ASN.1 structure definitions for RFC 5652 CMS EnvelopedData. These types are used by EncryptWithExternalWrap / DecryptWithExternalWrap to manually marshal a standards-conformant CMS EnvelopedData envelope around a DEK wrapped by an external service.

Index

Constants

This section is empty.

Variables

View Source
var ErrExternalWrapperNotImplemented = errors.New("envelope: external wrapper not implemented")

ErrExternalWrapperNotImplemented is reserved for future external-wrapper code paths that are not yet wired. The v1.25.0 RSAES-OAEP-SHA-256 + AES-256-GCM single-recipient path is fully implemented and no longer returns this sentinel; it remains as exported public API for forward compatibility (e.g., multi-recipient, alternative content-encryption algorithms).

Functions

func Decrypt

func Decrypt[T keypair.KeyPair](encrypted *encryption.EncryptedData, keyPair T, opts encryption.DecryptOptions) ([]byte, error)

Decrypt decrypts envelope-encrypted data.

Type parameter:

  • T: Key pair type constrained to keypair.KeyPair interface

Parameters:

  • encrypted: The envelope-encrypted data to decrypt
  • keyPair: The recipient's key pair (private key used for DEK decryption)
  • opts: Decryption options

Returns:

  • []byte: The decrypted plaintext data
  • error: Any error during key or data decryption

Example:

plaintext, err := envelope.Decrypt(encrypted, rsaKeys, opts)

func DecryptForRecipient

func DecryptForRecipient[T keypair.KeyPair](encrypted *encryption.EncryptedData, keyPair T, recipientIndex int, opts encryption.DecryptOptions) ([]byte, error)

DecryptForRecipient decrypts multi-recipient envelope data for a specific recipient.

Type parameter:

  • T: Key pair type constrained to keypair.KeyPair interface

Parameters:

  • encrypted: The multi-recipient encrypted data
  • keyPair: The recipient's key pair
  • recipientIndex: The index of this recipient in the recipient list
  • opts: Decryption options

Returns:

  • []byte: The decrypted data
  • error: Any error during decryption

Example:

// Decrypt as recipient at index 1
plaintext, err := envelope.DecryptForRecipient(encrypted, bobKeys, 1, opts)

func DecryptWithExternalWrap added in v1.25.0

func DecryptWithExternalWrap(
	ctx context.Context,
	cmsBytes []byte,
	wrapper ExternalWrapper,
) ([]byte, error)

DecryptWithExternalWrap parses a CMS EnvelopedData (produced by EncryptWithExternalWrap), asks the wrapper to unwrap the DEK, and AES-decrypts the bulk content. Returns the original plaintext.

func Encrypt

func Encrypt[T keypair.KeyPair](data []byte, keyPair T, opts encryption.EncryptOptions) (*encryption.EncryptedData, error)

Encrypt encrypts data using envelope encryption (hybrid approach) for efficient handling of data of any size with any supported key type.

Type parameter:

  • T: Key pair type constrained to keypair.KeyPair interface

Parameters:

  • data: The plaintext data to encrypt (any size supported)
  • keyPair: The recipient's key pair (public key used for DEK encryption)
  • opts: Encryption options (algorithm will be set to AlgorithmEnvelope)

Returns:

  • *encryption.EncryptedData: Encrypted data with envelope algorithm and combined payload
  • error: Any error during DEK generation, data encryption, or key encryption

Example:

// Works with any key type
rsaKeys, _ := algo.GenerateRSAKeyPair(2048)
largeFile := make([]byte, 10*1024*1024)  // 10MB file
encrypted, err := envelope.Encrypt(largeFile, rsaKeys, opts)

func EncryptForMultipleRecipients

func EncryptForMultipleRecipients(data []byte, recipients []keypair.GenericPublicKey, opts encryption.EncryptOptions) (*encryption.EncryptedData, error)

EncryptForMultipleRecipients encrypts data for multiple recipients.

Parameters:

  • data: The data to encrypt
  • recipients: List of recipient public keys
  • opts: Encryption options

Returns:

  • *encryption.EncryptedData: Multi-recipient encrypted data
  • error: Any error during encryption

Example:

recipients := []keypair.GenericPublicKey{aliceKey, bobKey, charlieKey}
encrypted, err := envelope.EncryptForMultipleRecipients(data, recipients, opts)

func EncryptForPublicKey

func EncryptForPublicKey[T keypair.PublicKey](data []byte, publicKey T, opts encryption.EncryptOptions) (*encryption.EncryptedData, error)

EncryptForPublicKey encrypts data for a specific public key using envelope encryption.

Type parameter:

  • T: Public key type constrained to keypair.PublicKey interface

Parameters:

  • data: The plaintext data to encrypt
  • publicKey: The recipient's public key
  • opts: Encryption options

Returns:

  • *encryption.EncryptedData: Envelope-encrypted data
  • error: Any error during encryption

Example:

publicKey := rsaKeys.PublicKey()
encrypted, err := envelope.EncryptForPublicKey(data, publicKey, opts)

func EncryptForPublicKeyAny

func EncryptForPublicKeyAny(data []byte, publicKey keypair.GenericPublicKey, opts encryption.EncryptOptions) (*encryption.EncryptedData, error)

EncryptForPublicKeyAny is a non-generic wrapper for EncryptForPublicKey that works with any public key type. This is used internally for dynamic dispatch when the public key type is not known at compile time.

func EncryptWithCertificate

func EncryptWithCertificate(data []byte, certificate *cert.Certificate, opts encryption.EncryptOptions) (*encryption.EncryptedData, error)

EncryptWithCertificate encrypts data using a certificate's public key.

Parameters:

  • data: The data to encrypt
  • certificate: The recipient's certificate
  • opts: Encryption options

Returns:

  • *encryption.EncryptedData: Envelope-encrypted data
  • error: Any error during encryption

Example:

encrypted, err := envelope.EncryptWithCertificate(data, recipientCert, opts)

func EncryptWithExternalWrap added in v1.25.0

func EncryptWithExternalWrap(
	ctx context.Context,
	data []byte,
	wrapper ExternalWrapper,
	recipientCert *x509.Certificate,
) ([]byte, error)

EncryptWithExternalWrap encrypts data via AES-256-GCM, asks the wrapper to wrap the DEK, and returns a DER-encoded CMS EnvelopedData ContentInfo.

recipientCert is embedded in the KeyTransRecipientInfo as issuer-and-serial-number. It is *not* used to perform any local crypto — the wrapper does all key wrapping.

func GetAlgorithmForKeyType

func GetAlgorithmForKeyType(keyType string) encryption.Algorithm

GetAlgorithmForKeyType returns the appropriate encryption algorithm for a key type

Types

type ExternalWrapper added in v1.25.0

type ExternalWrapper interface {
	WrapKey(ctx context.Context, dek []byte) (wrappedDEK []byte, err error)
	UnwrapKey(ctx context.Context, wrappedDEK []byte) (dek []byte, err error)
}

ExternalWrapper is implemented by callers that want gopki to assemble a standard RFC 5652 CMS EnvelopedData where the recipient's key-encryption key lives in an external service (HSM, KMS, smartcard).

WrapKey is called at encrypt time with a freshly-generated DEK (typically 32 bytes for AES-256); the implementation returns the DEK wrapped under the recipient's public-key algorithm + padding. UnwrapKey is called with the wrapped DEK at decrypt time and must return the original DEK bytes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL