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:
- Generate a random symmetric encryption key (Data Encryption Key - DEK)
- Encrypt the actual data with the DEK using AES-GCM
- Encrypt the DEK with the recipient's public key (Key Encryption Key - KEK)
- 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 ¶
- Variables
- func Decrypt[T keypair.KeyPair](encrypted *encryption.EncryptedData, keyPair T, opts encryption.DecryptOptions) ([]byte, error)
- func DecryptForRecipient[T keypair.KeyPair](encrypted *encryption.EncryptedData, keyPair T, recipientIndex int, ...) ([]byte, error)
- func DecryptWithExternalWrap(ctx context.Context, cmsBytes []byte, wrapper ExternalWrapper) ([]byte, error)
- func Encrypt[T keypair.KeyPair](data []byte, keyPair T, opts encryption.EncryptOptions) (*encryption.EncryptedData, error)
- func EncryptForMultipleRecipients(data []byte, recipients []keypair.GenericPublicKey, ...) (*encryption.EncryptedData, error)
- func EncryptForPublicKey[T keypair.PublicKey](data []byte, publicKey T, opts encryption.EncryptOptions) (*encryption.EncryptedData, error)
- func EncryptForPublicKeyAny(data []byte, publicKey keypair.GenericPublicKey, ...) (*encryption.EncryptedData, error)
- func EncryptWithCertificate(data []byte, certificate *cert.Certificate, opts encryption.EncryptOptions) (*encryption.EncryptedData, error)
- func EncryptWithExternalWrap(ctx context.Context, data []byte, wrapper ExternalWrapper, ...) ([]byte, error)
- func GetAlgorithmForKeyType(keyType string) encryption.Algorithm
- type ExternalWrapper
Constants ¶
This section is empty.
Variables ¶
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.