Last updated: March 15, 2026

To archive encrypted email securely, export your messages to MBOX or Maildir format via IMAP, then store your PGP/S/MIME private keys in a separate AES-256-encrypted container. never alongside the mail archive itself. This guide gives you three concrete methods (Python IMAP export, gpg-mailroom automation, and per-message Maildir encryption) with copy-paste commands, plus the key-backup, verification, and recovery steps that prevent your archive from becoming permanently unreadable.

Understanding the Encryption Challenge

Standard email archiving tools assume they can read message content. Encrypted email breaks this assumption. When you archive a PGP-encrypted message, you must preserve:

Without these elements, your archive becomes useless. A backup of encrypted emails without the keys is like locking your documents in a safe and losing the combination.

Why Standard Backup Tools Fail

Most backup utilities, including cloud sync services, Time Machine, and even dedicated email backup apps, treat encrypted email as opaque blobs. They copy the files, but they have no mechanism to ensure the corresponding private keys are also preserved. Five years from now, when you need to retrieve that encrypted message, you may find the keys expired, rotated off a lost device, or simply missing.

The other failure mode is the reverse: backing up keys alongside the encrypted messages in the same location. If an attacker gains access to your archive, they get everything they need to read it. Separation of archive and key material is the foundational principle of this guide.

Method 1 - Local MBOX Archive with Key Management

The most straightforward approach involves exporting your email to MBOX format while maintaining a separate, encrypted key backup.

Step 1 - Export Email Using Python and IMAP

import imaplib
import email
from email import policy
from email.generator import BytesGenerator
import os

def export_encrypted_emails(mailbox, output_dir, limit=None):
    """Export encrypted emails from IMAP to MBOX format."""
    mail.select(mailbox)

    # Search for all messages
    status, message_ids = mail.search(None, 'ALL')
    ids = message_ids[0].split()

    if limit:
        ids = ids[-limit:]

    for idx, msg_id in enumerate(ids):
        status, msg_data = mail.fetch(msg_id, '(RFC822)')
        raw_email = msg_data[0][1]

        # Parse and write to individual file
        msg = email.message_from_bytes(raw_email, policy=policy.default)

        # Preserve encryption headers
        filename = f"{output_dir}/{idx:06d}.eml"
        with open(filename, 'wb') as f:
            generator = BytesGenerator(f)
            generator.flatten(msg)

        print(f"Exported: {filename}")

Usage
mail = imaplib.IMAP4_SSL('imap.protonmail.com')
mail.login('your@email.com', 'app-password')
export_encrypted_emails(mail, './archive/2026-emails')

Step 2 - Backup Your Private Keys

Never store private keys in plain text. Use a dedicated encrypted container:

Create an encrypted archive of your keys
tar -czf - ~/.gnupg | gpg --symmetric \
    --cipher-algo AES256 \
    --compress-algo none \
    -o email-keys-backup-$(date +%Y%m%d).tar.gz.gpg

Verify the backup
gpg -d email-keys-backup-20260315.tar.gz.gpg | tar -tzf -

Store this encrypted key backup on separate media, ideally offline storage in a secure location.

Step 3 - Document Key Metadata

Before archiving, export a plain-text list of your key fingerprints and expiration dates. This metadata file lets you audit your archive without decrypting it:

Export key metadata to a signed, plaintext record
gpg --list-keys --with-fingerprint --with-colons > key-metadata.txt
gpg --clearsign --default-key your@email.com key-metadata.txt

Store key-metadata.txt.asc alongside your archive index. When you return to this archive years later, the signed metadata tells you exactly which key ID corresponds to each message range.

Method 2 - GPG-Mailroom for Systematic Archiving

For power users managing multiple accounts, gpg-mailroom provides an automated solution that handles encryption, signing, and storage rotation.

Installation and Basic Configuration

Clone and install gpg-mailroom
git clone https://github.com/loci/gpg-mailroom.git
cd gpg-mailroom
pip install -r requirements.txt

Configure your archive settings
cat > ~/.config/gpg-mailroom/config.yaml << 'EOF'
archive:
  retention_days: 2555  # 7 years
  compression: gpg
  destination: /backup/encrypted-archive

imap:
  server: imap.protonmail.com
  port: 993
  user: your@email.com

encryption:
  recipients:
    - your@email.com
  symmetric_backup: true
EOF

Running Scheduled Archives

Add to crontab for daily archives at 2 AM
0 2 * * * /usr/local/bin/gpg-mailroom --config ~/.config/gpg-mailroom/config.yaml

This approach automatically encrypts archives with your public key, ensuring only you can decrypt them.

Key Rotation Handling

One major advantage of gpg-mailroom is built-in support for key rotation. When your PGP key approaches expiration, configure the rotation schedule:

Add to config.yaml
key_rotation:
  warn_days_before_expiry: 90
  auto_reencrypt: true
  old_key_retention_days: 365

With auto_reencrypt enabled, the tool will re-encrypt archived messages with your new key before the old one expires. This prevents the common scenario where old archives become unreadable after key rotation.

Method 3 - Maildir with Per-Message Encryption

For developers who prefer filesystem-level control, storing emails in Maildir format with individually encrypted files provides maximum flexibility.

Python Script for Maildir Export

import os
import json
from pathlib import Path
import gnupg

GPG_HOME = os.path.expanduser('~/.gnupg')
gpg = gnupr.GPG(gnupghome=GPG_HOME)

def create_maildir_archive(source_dir, dest_dir, recipient):
    """Create Maildir with each email encrypted separately."""

    Path(dest_dir).mkdir(parents=True, exist_ok=True)
    Path(dest_dir, 'cur').mkdir(exist_ok=True)
    Path(dest_dir, 'new').mkdir(exist_ok=True)
    Path(dest_dir, 'tmp').mkdir(exist_ok=True)

    for eml_file in Path(source_dir).glob('*.eml'):
        with open(eml_file, 'rb') as f:
            email_data = f.read()

        # Encrypt each email individually
        encrypted = gpg.encrypt(email_data, recipient)

        # Write to Maildir
        output_path = Path(dest_dir, 'cur', f'{eml_file.stem}.gpg')
        with open(output_path, 'wb') as f:
            f.write(str(encrypted).encode())

        print(f"Encrypted: {eml_file.name} -> {output_path.name}")

Usage
create_maildir_archive('./emails', './maildir-archive', 'your@email.com')

This method allows you to retrieve specific messages without decrypting your entire archive.

Building a Search Index

Per-message encryption makes retrieval difficult without a search index. Generate an encrypted index of message metadata (sender, date, subject hash) at archive time:

import hashlib
import json

def build_archive_index(source_dir, output_file, recipient):
    """Build encrypted search index of message metadata."""
    index = []

    for eml_file in Path(source_dir).glob('*.eml'):
        with open(eml_file, 'rb') as f:
            raw = f.read()
        msg = email.message_from_bytes(raw)

        entry = {
            "file": eml_file.name,
            "date": msg.get("Date"),
            "from": msg.get("From"),
            "subject_hash": hashlib.sha256(
                msg.get("Subject", "").encode()
            ).hexdigest()[:16],
        }
        index.append(entry)

    index_json = json.dumps(index, indent=2).encode()
    encrypted_index = gpg.encrypt(index_json, recipient)

    with open(output_file, 'w') as f:
        f.write(str(encrypted_index))

Decrypt the index when you need to locate a message, then decrypt only the target file. This keeps the bulk of your archive sealed while enabling efficient retrieval.

Verification and Integrity Checking

Regardless of which method you choose, verification is essential. Create a checksum manifest for your archive:

Generate SHA256 checksums for your archive
sha256sum archive/*.eml > checksums.sha256

Sign the checksums
gpg --clearsign --default-key your@email.com checksums.sha256

Verify integrity
sha256sum -c checksums.sha256
gpg --verify checksums.sha256.asc checksums.sha256

Run these verification commands monthly and store the output with your archives.

Automated Integrity Verification Script

Manual verification is easy to forget. Automate it with a script that sends alerts on failure:

#!/bin/bash
ARCHIVE_DIR="/backup/encrypted-archive"
LOG="/var/log/archive-verify.log"

cd "$ARCHIVE_DIR"
sha256sum -c checksums.sha256 >> "$LOG" 2>&1

if [ $? -ne 0 ]; then
    echo "INTEGRITY FAILURE at $(date)" | mail -s "Archive Alert" admin@example.com
fi

Add this to your weekly cron schedule. An integrity failure could indicate corruption, hardware degradation, or tampering. catching it early is critical.

Storage Recommendations

Long-term encrypted email storage requires thoughtful media choices:

USB drives or external SSDs in a secure location work well for archives accessed infrequently. For off-site copies, services like Tresorit or SpiderOak provide zero-knowledge cloud encryption. Keep at least two copies on different media and account for key expiration and rotation when planning your schedule.

The 3-2-1 Rule for Email Archives

Apply the standard backup principle to email archives:

For encrypted email specifically, the key backup follows its own 3-2-1 rule. but never co-located with the corresponding archive. Keep keys and ciphertext physically and logically separated.

Media Longevity Considerations

USB drives fail. M-DISC optical media offers an extreme-longevity option for critical archives. For most use cases, annual refreshes to new drives and diversified cloud backup provide sufficient protection. Check drive health quarterly with smartctl -a /dev/sdX and replace any drive showing reallocated sectors or pending errors.

Frequently Asked Questions

Can I read archived encrypted emails without importing my key? No. PGP-encrypted messages require the corresponding private key to decrypt. This is by design. Maintain your key backups carefully, because there is no recovery path without them.

Should I decrypt emails before archiving? Only if the archive itself is protected by full-disk encryption on hardware you control exclusively. Decrypting before archiving creates a plaintext copy that any backup system or cloud sync can read. When in doubt, preserve the encrypted format and archive the keys separately.

What happens when my PGP key expires? Expired keys can still decrypt previously encrypted messages. expiration only prevents new encryption to that key. Import your old key into a fresh GPG keyring before attempting decryption. Without the old private key, those messages are permanently inaccessible.

How do I handle S/MIME certificates for corporate email? S/MIME certificate archives require exporting both the certificate and private key in PKCS#12 format: openssl pkcs12 -export -in cert.pem -inkey key.pem -out archive.p12. Store the .p12 file in the same encrypted container as your PGP keys.

Is ProtonMail’s Bridge export format compatible with these methods? Yes. ProtonMail Bridge exposes a local IMAP interface at 127.0.0.1:1143. Messages exported via Bridge are already decrypted to your local device, so encrypt the MBOX output before storing it.

Recovery Procedures

Document your recovery process before you need it. Your archival documentation should include:

  1. Location of encrypted key backups
  2. Passphrase retrieval process (password manager, secure notes)
  3. Step-by-step recovery commands for each archive format
  4. Verification procedures to confirm successful restoration

Test recovery on a clean system at least once to ensure your documentation is accurate.

Recovery Drill Checklist

Run a recovery drill annually:

A 30-minute annual drill is far less costly than discovering your archive is unusable when you actually need it.

Related Articles