Complete Guide to GPG/PGP Encryption: Implementation, Security, and Enterprise Best Practices
GNU Privacy Guard (GPG) represents the gold standard for asymmetric encryption and digital signature implementation in modern computing environments. This comprehensive guide covers GPG fundamentals, practical implementation strategies, enterprise deployment considerations, and advanced cryptographic security practices for systems administrators and security professionals.
Understanding GPG/PGP Cryptography
Cryptographic Foundation
GPG implements the OpenPGP standard (RFC 4880), utilizing asymmetric cryptography principles where each user maintains a mathematically related key pair:
Public Key Infrastructure
- Public Key: Used for encryption and signature verification (freely distributable)
- Private Key: Used for decryption and message signing (must remain confidential)
- Key Fingerprint: SHA-1 hash providing unique key identification
- User ID: Human-readable identification typically containing name and email
Cryptographic Algorithms
GPG supports multiple cipher suites:
# Display supported algorithms
gpg --version
# Common configurations:
# RSA: 2048-bit (minimum), 4096-bit (recommended), 8192-bit (maximum security)
# ECC: Curve25519, NIST P-256, NIST P-384, NIST P-521
# Symmetric: AES-256, AES-192, AES-128, ChaCha20
# Hash: SHA-256, SHA-512, SHA-1 (deprecated)
Installation and Environment Setup
Linux Distribution Installation
# Debian/Ubuntu
sudo apt update && sudo apt install gnupg2
# RHEL/CentOS/Rocky Linux
sudo dnf install gnupg2
# Arch Linux
sudo pacman -S gnupg
# Verify installation
gpg --version
macOS Installation
# Homebrew installation
brew install gnupg
# MacPorts installation
sudo port install gnupg2
# Verify GPG suite installation
gpg --version
which gpg
Windows Installation
- Download from: https://www.gnupg.org/download/
- Kleopatra GUI: Included with Gpg4win package
- Command-line tools: Available through WSL or native Windows build
Key Generation and Management
Advanced Key Generation
Standard Key Generation
# Interactive key generation
gpg --generate-key
# Full control key generation
gpg --full-generate-key
Batch Key Generation for Automation
# Create batch configuration file
cat > key-gen-config.txt << EOF
%echo Generating enterprise GPG key
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Subkey-Length: 4096
Name-Real: Enterprise Security
Name-Comment: Automated key generation
Name-Email: security@example.com
Expire-Date: 2y
Passphrase: $(openssl rand -base64 32)
%commit
%echo Key generation complete
EOF
# Generate key in batch mode
gpg --batch --generate-key key-gen-config.txt
Expert Key Generation with Custom Parameters
# Expert mode with ECC curves
gpg --expert --full-generate-key
# Generate Ed25519 signing key with Curve25519 encryption subkey
gpg --quick-generate-key "security@example.com" ed25519 sign 2y
gpg --quick-add-key $(gpg --list-secret-keys --with-colons security@example.com | awk -F: '/^fpr:/ {print $10}') cv25519 encrypt 2y
Key Export and Import Operations
Public Key Distribution
# Export ASCII-armored public key
gpg --armor --export security@example.com > public-key.asc
# Export binary public key
gpg --export security@example.com > public-key.gpg
# Export specific subkey
gpg --armor --export-subkeys security@example.com > subkeys.asc
# Verify exported key content
gpg --show-keys public-key.asc
Private Key Backup and Recovery
# Export private key (CRITICAL SECURITY OPERATION)
gpg --armor --export-secret-keys security@example.com > private-key-SECURE.asc
# Export private subkeys only
gpg --armor --export-secret-subkeys security@example.com > private-subkeys.asc
# Import private key
gpg --import private-key-SECURE.asc
# Secure deletion of temporary files
shred -vfz -n 3 private-key-SECURE.asc
Keyserver Operations and Management
Modern Keyserver Configuration
# Configure reliable keyserver
mkdir -p ~/.gnupg
cat > ~/.gnupg/dirmngr.conf << EOF
# Primary keyserver (modern, privacy-focused)
keyserver hkps://keys.openpgp.org
# Backup keyservers
keyserver hkps://keyserver.ubuntu.com
keyserver hkps://pgp.mit.edu
# Security settings
keyserver-options timeout=10
keyserver-options import-clean
keyserver-options export-clean
EOF
# Restart dirmngr daemon
gpgconf --kill dirmngr
Key Distribution and Retrieval
# Upload public key to keyserver
gpg --send-keys KEYID
# Retrieve key by ID
gpg --recv-keys 288DD1632F6E8951
# Search for keys by email (exact match)
gpg --search-keys security@example.com
# Search on specific keyserver
gpg --keyserver hkps://keyserver.ubuntu.com --search-keys "example.com"
# Refresh all keys from keyserver
gpg --refresh-keys
Advanced Key Verification
# Display key fingerprint
gpg --fingerprint security@example.com
# Show key details with validity
gpg --list-keys --with-colons security@example.com
# Check key signatures
gpg --list-sigs security@example.com
# Verify key against multiple sources
gpg --check-sigs security@example.com
Message Encryption and Decryption
Symmetric vs Asymmetric Encryption
Asymmetric Encryption (Standard GPG)
# Encrypt file for specific recipient
gpg --armor --encrypt --recipient security@example.com confidential.txt
# Encrypt for multiple recipients
gpg --armor --encrypt \
--recipient alice@example.com \
--recipient bob@example.com \
--recipient security@example.com \
sensitive-data.txt
# Encrypt and sign simultaneously
gpg --armor --encrypt --sign \
--recipient security@example.com \
--local-user sender@example.com \
important-document.txt
Symmetric Encryption for Personal Use
# Symmetric encryption with passphrase
gpg --symmetric --armor --cipher-algo AES256 personal-file.txt
# Symmetric encryption with custom compression
gpg --symmetric --armor \
--cipher-algo AES256 \
--compress-algo 2 \
--compress-level 9 \
large-backup.tar
Advanced Encryption Techniques
Stream Encryption for Large Files
# Encrypt large files efficiently
gpg --armor --encrypt --recipient security@example.com \
--compress-algo 2 --compress-level 6 \
< large-database-dump.sql > encrypted-dump.sql.asc
# Pipeline encryption
tar -czf - /important/directory | \
gpg --armor --encrypt --recipient security@example.com \
> encrypted-backup.tar.gz.asc
Batch Encryption Operations
#!/bin/bash
# Batch encryption script
RECIPIENT="security@example.com"
SOURCE_DIR="/path/to/sensitive/files"
ENCRYPTED_DIR="/path/to/encrypted/output"
mkdir -p "$ENCRYPTED_DIR"
find "$SOURCE_DIR" -type f -name "*.txt" | while read -r file; do
basename=$(basename "$file")
gpg --armor --encrypt --recipient "$RECIPIENT" \
--output "$ENCRYPTED_DIR/${basename}.asc" \
"$file"
echo "Encrypted: $basename"
done
Decryption and Verification
Standard Decryption Operations
# Decrypt to stdout
gpg --decrypt encrypted-file.asc
# Decrypt to specific file
gpg --decrypt encrypted-file.asc > decrypted-output.txt
# Decrypt with output specification
gpg --output decrypted-file.txt --decrypt encrypted-file.asc
# Batch decryption with verification
gpg --decrypt-files *.asc
Advanced Decryption with Logging
# Decrypt with detailed logging
gpg --verbose --decrypt \
--logger-file decryption.log \
--status-file status.log \
encrypted-file.asc
# Decrypt with passphrase from file (automation)
echo "passphrase" | gpg --batch --yes \
--passphrase-fd 0 \
--decrypt encrypted-file.asc
Digital Signatures and Verification
Signature Types and Use Cases
Clear-text Signatures
# Create clear-text signature
gpg --clear-sign --local-user security@example.com message.txt
# Verify clear-text signature
gpg --verify message.txt.asc
# Extract original text from clear-signed message
gpg --output original.txt --decrypt message.txt.asc
Detached Signatures
# Create detached signature
gpg --detach-sign --armor --local-user security@example.com software-release.tar.gz
# Verify detached signature (auto-detect original file)
gpg --verify software-release.tar.gz.asc
# Verify with explicit file specification
gpg --verify software-release.tar.gz.asc software-release.tar.gz
# Create signature with specific hash algorithm
gpg --detach-sign --armor --digest-algo SHA512 \
--local-user security@example.com \
critical-update.bin
Enterprise Signature Workflows
Code Signing Automation
#!/bin/bash
# Automated code signing script
SIGNING_KEY="code-signing@example.com"
BUILD_DIR="/path/to/build/artifacts"
SIGNATURE_DIR="/path/to/signatures"
mkdir -p "$SIGNATURE_DIR"
# Sign all binary artifacts
find "$BUILD_DIR" -type f \( -name "*.exe" -o -name "*.bin" -o -name "*.tar.gz" \) | while read -r artifact; do
basename=$(basename "$artifact")
# Create detached signature
gpg --detach-sign --armor \
--local-user "$SIGNING_KEY" \
--output "$SIGNATURE_DIR/${basename}.sig" \
"$artifact"
# Create SHA256 checksum
sha256sum "$artifact" > "$SIGNATURE_DIR/${basename}.sha256"
# Sign the checksum file
gpg --clear-sign --local-user "$SIGNING_KEY" \
"$SIGNATURE_DIR/${basename}.sha256"
echo "Signed: $basename"
done
Multi-signature Verification
#!/bin/bash
# Multi-signature verification script
verify_signatures() {
local file="$1"
local required_sigs=("security@example.com" "admin@example.com" "release@example.com")
local valid_sigs=0
for signer in "${required_sigs[@]}"; do
if gpg --verify "${file}.sig" "$file" 2>&1 | grep -q "$signer"; then
((valid_sigs++))
echo "✓ Valid signature from: $signer"
else
echo "✗ Missing or invalid signature from: $signer"
fi
done
if [[ $valid_sigs -eq ${#required_sigs[@]} ]]; then
echo "✓ All required signatures verified"
return 0
else
echo "✗ Signature verification failed ($valid_sigs/${#required_sigs[@]})"
return 1
fi
}
# Usage
verify_signatures "critical-release.tar.gz"
Trust Management and Web of Trust
Trust Levels and Policies
Understanding Trust Levels
# Display trust levels
gpg --list-keys --with-colons | grep "^pub" | cut -d: -f2,10
# Trust levels:
# 1 = Unknown (no trust assigned)
# 2 = Invalid (explicitly distrusted)
# 3 = Never (never trust this key)
# 4 = Marginal (some trust)
# 5 = Full (complete trust)
# 6 = Ultimate (your own keys)
Key Signing and Trust Assignment
# Sign a key locally (non-exportable signature)
gpg --lsign-key user@example.com
# Sign a key for public verification (exportable signature)
gpg --sign-key user@example.com
# Edit key trust level
gpg --edit-key user@example.com
# Commands within edit mode:
# trust (set trust level)
# sign (sign the key)
# save (save changes)
Enterprise Trust Configuration
# Set automatic trust for organizational keys
cat > ~/.gnupg/auto-trust-config << EOF
# Automatically trust keys from verified sources
auto-key-locate cert pka ldap keyserver
auto-key-retrieve
trust-model tofu+pgp
EOF
# Configure organizational keyring
gpg --import /etc/gnupg/organization-keys.gpg
gpg --edit-key organization@example.com trust quit
Certificate Authority Integration
LDAP Key Distribution
# Configure LDAP keyserver for corporate environment
cat >> ~/.gnupg/dirmngr.conf << EOF
# Corporate LDAP keyserver
ldapserver ldap://keys.corp.example.com:389
ldap-timeout 30
ldap-wrapper-program /usr/bin/ldap-wrapper
EOF
# Retrieve keys from LDAP
gpg --auto-key-locate ldap --search-keys user@corp.example.com
Enterprise Security Implementation
Automated Key Management
Centralized Key Distribution
#!/usr/bin/env python3
"""
Enterprise GPG Key Management System
"""
import gnupg
import subprocess
import json
import logging
from pathlib import Path
from typing import List, Dict, Optional
class EnterpriseGPGManager:
def __init__(self, gnupg_home: str = "~/.gnupg"):
self.gpg = gnupg.GPG(gnupghome=gnupg_home)
self.logger = logging.getLogger(__name__)
def generate_employee_key(self, name: str, email: str, department: str) -> Dict:
"""Generate standardized employee GPG key"""
key_config = {
'Key-Type': 'RSA',
'Key-Length': '4096',
'Subkey-Type': 'RSA',
'Subkey-Length': '4096',
'Name-Real': name,
'Name-Comment': f'{department} - {email.split("@")[0]}',
'Name-Email': email,
'Expire-Date': '2y',
'Preferences': 'SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed'
}
result = self.gpg.gen_key(self.gpg.gen_key_input(**key_config))
if result.fingerprint:
self.logger.info(f"Generated key for {email}: {result.fingerprint}")
return {
'fingerprint': result.fingerprint,
'email': email,
'name': name,
'department': department
}
else:
raise Exception(f"Key generation failed for {email}")
def distribute_public_key(self, fingerprint: str, keyservers: List[str]) -> bool:
"""Distribute public key to multiple keyservers"""
success_count = 0
for keyserver in keyservers:
try:
result = subprocess.run([
'gpg', '--keyserver', keyserver, '--send-keys', fingerprint
], capture_output=True, text=True, timeout=30)
if result.returncode == 0:
success_count += 1
self.logger.info(f"Successfully uploaded {fingerprint} to {keyserver}")
else:
self.logger.error(f"Failed to upload to {keyserver}: {result.stderr}")
except subprocess.TimeoutExpired:
self.logger.error(f"Timeout uploading to {keyserver}")
return success_count > 0
def backup_private_keys(self, backup_dir: str, encryption_recipient: str) -> None:
"""Secure backup of private keys"""
backup_path = Path(backup_dir)
backup_path.mkdir(parents=True, exist_ok=True)
secret_keys = self.gpg.list_keys(True)
for key in secret_keys:
fingerprint = key['fingerprint']
email = key['uids'][0]
# Export private key
private_key = self.gpg.export_keys(fingerprint, True, armor=True)
# Encrypt backup with organizational key
encrypted_backup = self.gpg.encrypt(
private_key,
recipients=[encryption_recipient],
armor=True
)
backup_file = backup_path / f"{fingerprint}-private.asc"
backup_file.write_text(str(encrypted_backup))
self.logger.info(f"Backed up private key for {email}")
# Configuration management
class GPGConfigManager:
@staticmethod
def deploy_enterprise_config(config_dir: str = "~/.gnupg") -> None:
"""Deploy standardized GPG configuration"""
config_path = Path(config_dir).expanduser()
config_path.mkdir(mode=0o700, exist_ok=True)
# GPG configuration
gpg_conf = config_path / "gpg.conf"
gpg_conf.write_text("""
# Enterprise GPG Configuration
default-key security@example.com
keyserver hkps://keys.openpgp.org
keyserver-options timeout=10
keyserver-options import-clean
keyserver-options export-clean
# Cryptographic preferences
personal-cipher-preferences AES256 AES192 AES
personal-digest-preferences SHA512 SHA384 SHA256
personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed
# Security settings
require-cross-certification
no-emit-version
no-comments
use-agent
pinentry-mode loopback
# Display options
list-options show-uid-validity
verify-options show-uid-validity
with-fingerprint
with-key-origin
""")
# dirmngr configuration
dirmngr_conf = config_path / "dirmngr.conf"
dirmngr_conf.write_text("""
# Enterprise dirmngr Configuration
keyserver hkps://keys.openpgp.org
keyserver hkps://keyserver.ubuntu.com
# Corporate keyserver (if available)
# ldapserver ldap://keys.corp.example.com:389
# Security settings
honor-http-proxy
disable-http
""")
# Set appropriate permissions
gpg_conf.chmod(0o600)
dirmngr_conf.chmod(0o600)
# Example usage
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
# Initialize enterprise GPG manager
gpg_manager = EnterpriseGPGManager()
# Deploy configuration
GPGConfigManager.deploy_enterprise_config()
# Generate employee key
employee_key = gpg_manager.generate_employee_key(
"John Doe",
"john.doe@example.com",
"IT Security"
)
# Distribute to keyservers
keyservers = [
"hkps://keys.openpgp.org",
"hkps://keyserver.ubuntu.com"
]
gpg_manager.distribute_public_key(
employee_key['fingerprint'],
keyservers
)
# Backup private keys
gpg_manager.backup_private_keys(
"/secure/gpg-backups",
"backup@example.com"
)
Secure Communication Protocols
Email Integration with GPG
# Configure Mutt with GPG
cat > ~/.muttrc << EOF
# GPG Configuration
set pgp_default_key = "security@example.com"
set pgp_sign_as = "security@example.com"
set pgp_timeout = 300
set pgp_use_gpg_agent = yes
set pgp_autosign = yes
set pgp_autoencrypt = yes
set pgp_replysign = yes
set pgp_replyencrypt = yes
# Key bindings
bind compose p pgp-menu
macro compose Y pfy "send mail without GPG"
EOF
# Thunderbird integration (Enigmail successor)
# Install Thunderbird with built-in OpenPGP support
# Configure via: Account Settings > End-to-End Encryption
Git Commit Signing
# Configure Git for commit signing
git config --global user.signingkey security@example.com
git config --global commit.gpgsign true
git config --global tag.gpgsign true
# Sign individual commit
git commit -S -m "Signed commit message"
# Verify signed commits
git log --show-signature
# Configure Git hooks for mandatory signing
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# Ensure all commits are GPG signed
if ! git rev-parse --verify HEAD >/dev/null 2>&1; then
# Initial commit
exit 0
fi
# Check if commit is signed
if ! git cat-file commit HEAD | grep -q "gpgsig"; then
echo "Error: Commit must be GPG signed"
echo "Use: git commit -S"
exit 1
fi
EOF
chmod +x .git/hooks/pre-commit
Infrastructure Automation
Ansible GPG Integration
---
# Ansible playbook for GPG deployment
- name: Deploy Enterprise GPG Configuration
hosts: all
become: yes
vars:
gpg_admin_key: "security@example.com"
tasks:
- name: Install GPG packages
package:
name:
- gnupg2
- pinentry-curses
state: present
- name: Create GPG directory for users
file:
path: "/home/{{ item }}/.gnupg"
state: directory
mode: '0700'
owner: "{{ item }}"
group: "{{ item }}"
loop: "{{ ansible_users }}"
- name: Deploy GPG configuration
template:
src: gpg.conf.j2
dest: "/home/{{ item }}/.gnupg/gpg.conf"
mode: '0600'
owner: "{{ item }}"
group: "{{ item }}"
loop: "{{ ansible_users }}"
- name: Import organizational public keys
shell: |
sudo -u {{ item }} gpg --import /etc/gpg/org-keys.asc
loop: "{{ ansible_users }}"
- name: Trust organizational keys
shell: |
echo "5" | sudo -u {{ item }} gpg --command-fd 0 --edit-key "{{ gpg_admin_key }}" trust quit
loop: "{{ ansible_users }}"
Advanced Security Practices
Hardware Security Modules (HSM)
YubiKey Integration
# Install YubiKey tools
sudo apt install yubikey-manager scdaemon
# Generate keys on YubiKey
gpg --card-edit
# Commands:
# admin
# generate (generate keys on card)
# quit
# Move existing keys to YubiKey
gpg --edit-key security@example.com
# Commands:
# keytocard (move primary key)
# key 1 (select subkey)
# keytocard (move subkey)
# save
# Backup encryption key before moving to card
gpg --armor --export-secret-subkeys security@example.com > backup-subkeys.asc
Smart Card Configuration
# Configure smart card parameters
gpg --card-edit
# Available commands:
# admin - enable admin commands
# passwd - change PIN/Admin PIN
# name - set cardholder name
# url - set URL for public key retrieval
# forcesig - require PIN for each signature
Air-Gapped Key Generation
Offline Key Ceremony
#!/bin/bash
# Secure offline key generation script
set -euo pipefail
# Ensure we're on an air-gapped system
if ping -c 1 8.8.8.8 &> /dev/null; then
echo "ERROR: Network connectivity detected. Disconnect before proceeding."
exit 1
fi
# Secure random number generation
echo "Generating entropy..."
dd if=/dev/urandom of=/tmp/entropy bs=4096 count=1024
cat /tmp/entropy > /dev/random
# Create temporary GPG home
TEMP_GNUPG=$(mktemp -d)
chmod 700 "$TEMP_GNUPG"
export GNUPGHOME="$TEMP_GNUPG"
# Generate master key
gpg --batch --generate-key << EOF
%echo Generating master key
Key-Type: RSA
Key-Length: 4096
Name-Real: Critical Infrastructure Master Key
Name-Email: master@example.com
Expire-Date: 5y
Passphrase: $(head -c 32 /dev/urandom | base64)
%commit
%echo Master key generation complete
EOF
# Generate subkeys
MASTER_FPR=$(gpg --list-secret-keys --with-colons | awk -F: '/^fpr:/ {print $10}')
# Signing subkey
gpg --quick-add-key "$MASTER_FPR" rsa4096 sign 2y
# Encryption subkey
gpg --quick-add-key "$MASTER_FPR" rsa4096 encrypt 2y
# Authentication subkey
gpg --quick-add-key "$MASTER_FPR" rsa4096 auth 2y
echo "Key ceremony completed. Secure backup required."
Cryptographic Best Practices
Algorithm Selection
# Modern cryptographic preferences
cat > ~/.gnupg/gpg.conf << EOF
# Cipher preferences (strongest first)
personal-cipher-preferences AES256 AES192 AES CAMELLIA256 CAMELLIA192 CAMELLIA128
# Digest preferences (strongest first)
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
# Compression preferences
personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
# Default algorithms for new keys
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAMELLIA256 CAMELLIA192 CAMELLIA128 ZLIB BZIP2 ZIP Uncompressed
# Disable weak algorithms
weak-digest SHA1
EOF
Key Rotation Procedures
#!/bin/bash
# Automated key rotation script
OLD_KEY="old-key@example.com"
NEW_KEY="new-key@example.com"
KEYSERVERS=("keys.openpgp.org" "keyserver.ubuntu.com")
# Generate new key
echo "Generating new key..."
gpg --quick-generate-key "$NEW_KEY" rsa4096 encrypt,sign 2y
# Cross-sign keys
echo "Cross-signing keys..."
gpg --default-key "$OLD_KEY" --sign-key "$NEW_KEY"
gpg --default-key "$NEW_KEY" --sign-key "$OLD_KEY"
# Create transition statement
cat > transition-statement.txt << EOF
I am transitioning my GPG key from:
Old key: $(gpg --fingerprint "$OLD_KEY" | grep fingerprint | sed 's/.*= //')
New key: $(gpg --fingerprint "$NEW_KEY" | grep fingerprint | sed 's/.*= //')
The old key will remain valid for 90 days for verification purposes.
Please update your keyring and use the new key for future communications.
Transition date: $(date -u)
EOF
# Sign transition statement
gpg --clear-sign --local-user "$OLD_KEY" transition-statement.txt
gpg --detach-sign --local-user "$NEW_KEY" transition-statement.txt.asc
# Upload new key to keyservers
for keyserver in "${KEYSERVERS[@]}"; do
gpg --keyserver "hkps://$keyserver" --send-keys "$NEW_KEY"
done
echo "Key rotation completed. Distribute transition statement."
Compliance and Auditing
Regulatory Compliance
FIPS 140-2 Compliance
# FIPS-compliant GPG configuration
cat > ~/.gnupg/fips-gpg.conf << EOF
# FIPS 140-2 compliant configuration
personal-cipher-preferences AES256 AES192 AES
personal-digest-preferences SHA256 SHA384 SHA512
personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
# Disable non-FIPS algorithms
disable-cipher-algo CAST5
disable-cipher-algo BLOWFISH
disable-cipher-algo TWOFISH
disable-pubkey-algo DSA
disable-digest-algo MD5
disable-digest-algo SHA1
EOF
SOC 2 Key Management Controls
#!/usr/bin/env python3
"""
SOC 2 Compliance Monitoring for GPG Key Management
"""
import subprocess
import json
import datetime
from typing import Dict, List
class SOC2GPGAuditor:
def __init__(self):
self.audit_log = []
def check_key_expiration(self) -> Dict:
"""Monitor key expiration for SOC 2 compliance"""
result = subprocess.run(['gpg', '--list-keys', '--with-colons'],
capture_output=True, text=True)
keys_expiring = []
current_date = datetime.datetime.now()
for line in result.stdout.split('\n'):
if line.startswith('pub:'):
fields = line.split(':')
if len(fields) > 6 and fields[6]:
exp_date = datetime.datetime.fromtimestamp(int(fields[6]))
days_to_expire = (exp_date - current_date).days
if days_to_expire <= 30:
keys_expiring.append({
'key_id': fields[4],
'expiration': exp_date.isoformat(),
'days_remaining': days_to_expire
})
audit_entry = {
'timestamp': current_date.isoformat(),
'check_type': 'key_expiration',
'keys_expiring': keys_expiring,
'compliance_status': 'WARNING' if keys_expiring else 'PASS'
}
self.audit_log.append(audit_entry)
return audit_entry
def verify_key_strengths(self) -> Dict:
"""Verify cryptographic strength compliance"""
result = subprocess.run(['gpg', '--list-keys', '--with-colons'],
capture_output=True, text=True)
weak_keys = []
for line in result.stdout.split('\n'):
if line.startswith('pub:'):
fields = line.split(':')
key_length = int(fields[2]) if fields[2] else 0
algorithm = fields[3]
# Check for minimum key strength
if algorithm == '1' and key_length < 2048: # RSA
weak_keys.append({
'key_id': fields[4],
'algorithm': 'RSA',
'length': key_length,
'minimum_required': 2048
})
audit_entry = {
'timestamp': datetime.datetime.now().isoformat(),
'check_type': 'key_strength',
'weak_keys': weak_keys,
'compliance_status': 'FAIL' if weak_keys else 'PASS'
}
self.audit_log.append(audit_entry)
return audit_entry
def generate_compliance_report(self) -> str:
"""Generate comprehensive compliance report"""
report = {
'report_date': datetime.datetime.now().isoformat(),
'auditor': 'SOC2GPGAuditor',
'checks_performed': len(self.audit_log),
'audit_log': self.audit_log
}
return json.dumps(report, indent=2)
# Example usage
if __name__ == "__main__":
auditor = SOC2GPGAuditor()
# Perform compliance checks
expiration_check = auditor.check_key_expiration()
strength_check = auditor.verify_key_strengths()
# Generate report
compliance_report = auditor.generate_compliance_report()
# Save report
with open(f"gpg_compliance_report_{datetime.datetime.now().strftime('%Y%m%d')}.json", 'w') as f:
f.write(compliance_report)
Incident Response Procedures
Key Compromise Response
#!/bin/bash
# GPG Key Compromise Response Script
COMPROMISED_KEY="$1"
EMERGENCY_CONTACT="security@example.com"
if [[ -z "$COMPROMISED_KEY" ]]; then
echo "Usage: $0 <compromised-key-id>"
exit 1
fi
echo "INCIDENT: GPG Key Compromise Response Initiated"
echo "Compromised Key: $COMPROMISED_KEY"
echo "Timestamp: $(date -u)"
# 1. Revoke the compromised key
echo "Step 1: Generating revocation certificate..."
gpg --output "revoke-${COMPROMISED_KEY}.asc" \
--gen-revoke "$COMPROMISED_KEY"
# 2. Import and publish revocation
echo "Step 2: Publishing revocation certificate..."
gpg --import "revoke-${COMPROMISED_KEY}.asc"
gpg --send-keys "$COMPROMISED_KEY"
# 3. Generate incident report
cat > "incident-report-${COMPROMISED_KEY}.txt" << EOF
GPG KEY COMPROMISE INCIDENT REPORT
Incident ID: GPG-$(date +%Y%m%d-%H%M%S)
Date/Time: $(date -u)
Compromised Key: $COMPROMISED_KEY
Response Action: Key revoked and revocation published
Key Details:
$(gpg --list-key "$COMPROMISED_KEY")
Response Actions Taken:
1. Revocation certificate generated
2. Key revoked in local keyring
3. Revocation published to keyservers
4. Incident report generated
Next Steps Required:
1. Notify all users of key compromise
2. Generate replacement key if needed
3. Update any automated systems using this key
4. Review access logs for unauthorized usage
EOF
# 4. Notify security team
echo "Step 3: Notifying security team..."
gpg --encrypt --armor --recipient "$EMERGENCY_CONTACT" \
--output "incident-report-${COMPROMISED_KEY}.asc" \
"incident-report-${COMPROMISED_KEY}.txt"
echo "Key compromise response completed."
echo "Incident report: incident-report-${COMPROMISED_KEY}.txt"
echo "Encrypted report: incident-report-${COMPROMISED_KEY}.asc"
This comprehensive guide provides enterprise-grade GPG implementation strategies, ensuring robust cryptographic security for modern infrastructure environments. Regular training, proper key management, and adherence to security best practices ensure effective protection of sensitive communications and data integrity.