Inside Envelope Encryption: The Pattern Behind Secure Systems by Kanchan Sikder on August 25, 2026 21 views

The Problem Encryption Alone Can’t Solve
When we think about encryption, our attention naturally goes to the data.
- Medical records.
- Financial transactions.
- Identity documents.
- Personal photos.
These are the assets we want to protect.
Yet modern security systems don’t spend most of their effort protecting the data itself. They spend it protecting something much smaller i.e. the encryption keys.
At first, this might sound surprising.
An encrypted document without its key is nothing more than a sequence of unreadable bytes. The strength of the encryption depends not only on the algorithm but also on keeping the key secure. Lose control of the key, and the protection disappears regardless of how strong the encryption algorithm is.
This changes the problem entirely.
Building a secure application isn’t just about encrypting data. It’s about deciding how encryption keys are created, stored, accessed, rotated, and eventually retired.
As applications grow, this challenge becomes increasingly important.
A cloud application might store millions of encrypted documents. Each document must remain confidential, keys must be rotated periodically, access should be auditable, and a compromised key shouldn’t expose every document in the system.
These requirements aren’t solved by choosing a stronger encryption algorithm.
They’re solved by designing a better key management strategy.
This is the problem envelope encryption was created to solve.
What is Envelope Encryption?
Envelope encryption is a cryptographic pattern that uses two keys:
- a Data Encryption Key (DEK) to encrypt the data
- a Key Encryption Key (KEK), managed by a Key Management Service (KMS), to encrypt the DEK
The encrypted data, along with the wrapped DEK, is then stored in the database. When the data needs to be decrypted, the KMS first unwraps the DEK, which is then used to decrypt the data.
Instead of asking one key to do everything, the system separates data encryption from key protection.
This separation offers flexibility that would be difficult to achieve with a single key. Data can be encrypted efficiently using symmetric algorithms such as AES-GCM, while the KEK remains inside a managed key management service, such as Google Cloud KMS, AWS KMS, or Azure Key Vault, where access can be controlled, audited, and rotated independently.

How Envelope Encryption Works
Step 1 :  Generate a DEK Locally
The application generates a random symmetric encryption key locally.
This key is called the Data Encryption Key (DEK).
# Generate DEK
dek = KmsService.generate_dek()
Step 2 :  Encrypt the Document
The DEK is then used to encrypt the large document locally using a fast symmetric encryption algorithm such as AES-256.
Since this encryption happens locally:
- large files can be processed efficiently
- no payload size limitations exist
- encryption becomes significantly faster
@staticmethod
def encrypt_document(plaintext: str, dek: bytes):
aesgcm = AESGCM(dek)
# Generate a random nonce (IV)
nonce = secrets.token_bytes(12)
# Encrypt the document
ciphertext = aesgcm.encrypt(
nonce,
plaintext.encode(),
None
)
return {
"ciphertext": base64.b64encode(ciphertext).decode(),
"nonce": base64.b64encode(nonce).decode()
}
# Encrypt document locally
encrypted_data = KmsService.encrypt_document(
plaintext=document,
dek=dek
)
The nonce must be unique for every encryption operation when using AES-GCM.
Step 3 :  Protect the DEK Using KMS
Instead of sending the large document to KMS, only the small DEK is sent.
KMS encrypts the DEK using a securely managed master key (KEK).
The result is an encrypted version of the DEK.
# Encrypt DEK using KMS
encrypted_dek = KmsService.encrypt_dek(dek)
Step 4 :  Store Everything
The system stores:
- the encrypted document
- the encrypted DEK
- optional metadata such as IVs, algorithms, or key versions
At no point is the plaintext DEK permanently stored.
How Decryption Works
During decryption, the process simply happens in reverse.
Step 1 :  Retrieve the Encrypted DEK
The application fetches the encrypted DEK from storage.
Step 2 :  Decrypt the DEK Using KMS
The encrypted DEK is sent to KMS.
decrypted_dek = KmsService.decrypt_dek(
encrypted_dek
)
KMS decrypts it and returns the original DEK securely.
Step 3 :  Decrypt the Document
The plaintext DEK is then used locally to decrypt the encrypted document.
@staticmethod
def decrypt_document(ciphertext: str, nonce: str, dek: bytes) -> str:
"""
Decrypts an AES-GCM encrypted document.
Args:
ciphertext (str): Base64 encoded encrypted document
nonce (str): Base64 encoded nonce (IV)
dek (bytes): Plaintext Data Encryption Key (DEK)
Returns:
str: Decrypted plaintext document
"""
# Initialize AESGCM with the DEK
aesgcm = AESGCM(dek)
# Decode base64 values
ciphertext_bytes = base64.b64decode(ciphertext)
nonce_bytes = base64.b64decode(nonce)
# Decrypt the ciphertext
plaintext = aesgcm.decrypt(
nonce_bytes,
ciphertext_bytes,
None
)
# Convert bytes back to string
return plaintext.decode()
# Decrypt document
document = KmsService.decrypt_document(
ciphertext,
nonce,
decrypted_dek
)
And just like that, the original data is restored.
What Problems Does Envelope Encryption Solve?
Envelope encryption introduces additional complexity, but each part of its design addresses a real engineering challenge.
Protecting Encryption Keys
Encryption is only as secure as the keys protecting it. By encrypting the DEK with a KEK managed by a Key Management Service (KMS), the encryption keys receive stronger protection than the encrypted data itself.
Encrypting Large Amounts of Data Efficiently
Large files are encrypted locally using a fast symmetric algorithm such as AES-GCM, while only the small DEK is sent to the KMS. This avoids performance bottlenecks and KMS payload limitations.
Limiting the Impact of Key Compromise
Using a unique DEK for each document prevents a single compromised key from exposing all encrypted data. The impact is isolated to the data protected by that specific DEK.
Simplifying Key Rotation
The KEK can be rotated without re-encrypting every document. Only the encrypted DEKs need to be reprotected, making key rotation faster and operationally simpler.
Separating Responsibilities
The application is responsible for encrypting data, while the KMS is responsible for protecting encryption keys. This clear separation improves security, scalability, and maintainability.
Encrypted Takeaway
Modern security isn’t built on stronger algorithms alone. It’s built on thoughtful architecture.
Envelope encryption is a great example of this principle. Rather than relying on a single key to solve every problem, it separates the responsibilities of encrypting data and protecting encryption keys. The result is a system that’s not only secure, but also scalable, manageable, and practical for real-world applications.
Good security architecture isn’t about forcing one service to do everything. It’s about assigning each component the responsibility it’s designed to handle and letting those components work together.