Key Rotation is the process of periodic renewal of cryptographic keys to maintain security, reduce compromise risk, and comply with security best practices.

What is Key Rotation?

Key rotation is a security practice that consists of regularly replacing cryptographic keys used to encrypt and decrypt data, authenticate users, and protect communications.

Importance of Rotation

Risk Reduction

  • Limited Compromise: Limits impact of compromised keys
  • Exposure Window: Reduces exposure window
  • Attacks: Hinders brute force attacks
  • Security: Maintains long-term security

Regulatory Compliance

  • Standards: Compliance with security standards
  • Regulations: Regulatory compliance
  • Audits: Audit preparation
  • Certifications: Certification maintenance

Best Practices

  • Industry: Industry standards
  • Recommendations: Expert recommendations
  • Security: Robust security practices
  • Management: Proactive risk management

Rotation Types

Scheduled Rotation

  • Schedule: Rotation according to fixed schedule
  • Periodic: Regular rotation (daily, weekly, monthly)
  • Automatic: Automatic rotation
  • Predictable: Easy to plan

Event-Based Rotation

  • Compromise: Rotation after suspected compromise
  • Personnel: Rotation after personnel changes
  • System: Rotation after system changes
  • Emergency: Emergency rotation

Gradual Rotation

  • Transition: Gradual transition between keys
  • Coexistence: Temporary key coexistence
  • Migration: Gradual data migration
  • Compatibility: Compatibility maintenance

Rotation Strategies

Simple Rotation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import datetime
import secrets
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

class SimpleKeyRotation:
    def __init__(self, rotation_interval_days=90):
        self.rotation_interval = datetime.timedelta(days=rotation_interval_days)
        self.current_key = None
        self.key_history = []
        self.last_rotation = None
    
    def generate_new_key(self, key_size=2048):
        """Generate new key"""
        private_key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=key_size
        )
        return private_key
    
    def should_rotate(self):
        """Check if key rotation is necessary"""
        if self.last_rotation is None:
            return True
        
        return datetime.datetime.now() - self.last_rotation > self.rotation_interval
    
    def rotate_key(self):
        """Rotate the key"""
        if not self.should_rotate():
            return False
        
        # Generate new key
        new_key = self.generate_new_key()
        
        # Save previous key in history
        if self.current_key is not None:
            self.key_history.append({
                'key': self.current_key,
                'created': self.last_rotation,
                'retired': datetime.datetime.now()
            })
        
        # Update current key
        self.current_key = new_key
        self.last_rotation = datetime.datetime.now()
        
        return True

# Usage example
key_rotation = SimpleKeyRotation(rotation_interval_days=30)
if key_rotation.should_rotate():
    key_rotation.rotate_key()

Rotation with Data Migration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class DataMigrationKeyRotation:
    def __init__(self, encryption_service):
        self.encryption_service = encryption_service
        self.old_key = None
        self.new_key = None
        self.migration_status = "idle"
    
    def start_rotation(self):
        """Start rotation process"""
        # Generate new key
        self.new_key = self.generate_new_key()
        
        # Keep previous key
        self.old_key = self.encryption_service.get_current_key()
        
        # Change status
        self.migration_status = "migrating"
        
        return True
    
    def migrate_data(self, encrypted_data):
        """Migrate encrypted data"""
        if self.migration_status != "migrating":
            raise ValueError("Rotation not started")
        
        # Decrypt with old key
        decrypted_data = self.encryption_service.decrypt(
            encrypted_data, 
            self.old_key
        )
        
        # Encrypt with new key
        new_encrypted_data = self.encryption_service.encrypt(
            decrypted_data, 
            self.new_key
        )
        
        return new_encrypted_data
    
    def complete_rotation(self):
        """Complete rotation"""
        if self.migration_status != "migrating":
            raise ValueError("Migration not in progress")
        
        # Update encryption service
        self.encryption_service.set_current_key(self.new_key)
        
        # Clean old key
        self.old_key = None
        self.migration_status = "completed"
        
        return True

# Usage example
class EncryptionService:
    def __init__(self):
        self.current_key = None
    
    def get_current_key(self):
        return self.current_key
    
    def set_current_key(self, key):
        self.current_key = key
    
    def encrypt(self, data, key):
        # Implement encryption
        return f"encrypted_{data}"
    
    def decrypt(self, encrypted_data, key):
        # Implement decryption
        return encrypted_data.replace("encrypted_", "")

encryption_service = EncryptionService()
rotation = DataMigrationKeyRotation(encryption_service)

Rotation Automation

Automatic Rotation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import schedule
import time
import logging
from datetime import datetime

class AutomatedKeyRotation:
    def __init__(self, key_manager, rotation_interval_hours=24):
        self.key_manager = key_manager
        self.rotation_interval = rotation_interval_hours
        self.logger = logging.getLogger(__name__)
    
    def setup_schedule(self):
        """Setup rotation schedule"""
        schedule.every(self.rotation_interval).hours.do(self.rotate_keys)
        self.logger.info(f"Rotation scheduled every {self.rotation_interval} hours")
    
    def rotate_keys(self):
        """Rotate keys automatically"""
        try:
            self.logger.info("Starting automatic key rotation")
            
            # Get keys that need rotation
            keys_to_rotate = self.key_manager.get_keys_for_rotation()
            
            for key_id in keys_to_rotate:
                self.key_manager.rotate_key(key_id)
                self.logger.info(f"Key {key_id} rotated successfully")
            
            self.logger.info("Automatic rotation completed")
            
        except Exception as e:
            self.logger.error(f"Error in automatic rotation: {e}")
    
    def start_scheduler(self):
        """Start scheduler"""
        self.setup_schedule()
        
        while True:
            schedule.run_pending()
            time.sleep(60)  # Check every minute

# Usage example
class KeyManager:
    def __init__(self):
        self.keys = {}
    
    def get_keys_for_rotation(self):
        """Get keys that need rotation"""
        keys_to_rotate = []
        for key_id, key_info in self.keys.items():
            if self.should_rotate_key(key_info):
                keys_to_rotate.append(key_id)
        return keys_to_rotate
    
    def should_rotate_key(self, key_info):
        """Check if a key needs rotation"""
        # Implement rotation logic
        return True
    
    def rotate_key(self, key_id):
        """Rotate a specific key"""
        # Implement key rotation
        pass

key_manager = KeyManager()
automated_rotation = AutomatedKeyRotation(key_manager)
# automated_rotation.start_scheduler()  # Run in separate thread

Event-Driven Rotation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class EventDrivenKeyRotation:
    def __init__(self, key_manager):
        self.key_manager = key_manager
        self.event_handlers = {
            'key_compromise': self.handle_compromise,
            'personnel_change': self.handle_personnel_change,
            'system_change': self.handle_system_change,
            'emergency': self.handle_emergency
        }
    
    def handle_event(self, event_type, event_data):
        """Handle rotation event"""
        if event_type in self.event_handlers:
            self.event_handlers[event_type](event_data)
        else:
            raise ValueError(f"Unsupported event type: {event_type}")
    
    def handle_compromise(self, event_data):
        """Handle key compromise"""
        key_id = event_data.get('key_id')
        if key_id:
            self.key_manager.rotate_key_immediately(key_id)
            self.key_manager.revoke_key(key_id)
    
    def handle_personnel_change(self, event_data):
        """Handle personnel change"""
        user_id = event_data.get('user_id')
        if user_id:
            self.key_manager.rotate_user_keys(user_id)
    
    def handle_system_change(self, event_data):
        """Handle system change"""
        system_id = event_data.get('system_id')
        if system_id:
            self.key_manager.rotate_system_keys(system_id)
    
    def handle_emergency(self, event_data):
        """Handle emergency rotation"""
        self.key_manager.rotate_all_keys()

# Usage example
event_rotation = EventDrivenKeyRotation(key_manager)
event_rotation.handle_event('key_compromise', {'key_id': 'key_123'})

Best Practices

Rotation Frequency

  • Session Keys: Frequent rotation (daily/weekly)
  • Encryption Keys: Regular rotation (monthly/quarterly)
  • Signing Keys: Less frequent rotation (annual)
  • Root Keys: Very infrequent rotation

Lifecycle Management

  • Generation: Secure key generation
  • Distribution: Secure distribution
  • Usage: Controlled usage
  • Rotation: Scheduled rotation
  • Revocation: Revocation when necessary
  • Destruction: Secure destruction

Monitoring and Auditing

  • Logging: Logging of all operations
  • Monitoring: Continuous monitoring
  • Alerts: Alerts for failures
  • Audit: Regular audit

Rotation Tools

AWS KMS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import boto3
from botocore.exceptions import ClientError

class AWSKMSKeyRotation:
    def __init__(self, region_name='us-east-1'):
        self.kms_client = boto3.client('kms', region_name=region_name)
    
    def enable_automatic_rotation(self, key_id, rotation_period_days=365):
        """Enable automatic rotation"""
        try:
            response = self.kms_client.enable_key_rotation(
                KeyId=key_id
            )
            return response
        except ClientError as e:
            print(f"Error enabling rotation: {e}")
            return None
    
    def rotate_key(self, key_id):
        """Rotate key manually"""
        try:
            response = self.kms_client.create_key(
                Description=f"Rotated key for {key_id}",
                KeyUsage='ENCRYPT_DECRYPT'
            )
            return response['KeyMetadata']['KeyId']
        except ClientError as e:
            print(f"Error rotating key: {e}")
            return None

# Usage example
kms_rotation = AWSKMSKeyRotation()
kms_rotation.enable_automatic_rotation('alias/my-key')

HashiCorp Vault

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import hvac

class VaultKeyRotation:
    def __init__(self, vault_url, token):
        self.client = hvac.Client(url=vault_url, token=token)
    
    def rotate_transit_key(self, key_name):
        """Rotate transit key"""
        try:
            response = self.client.secrets.transit.rotate_key(
                name=key_name
            )
            return response
        except Exception as e:
            print(f"Error rotating key: {e}")
            return None
    
    def rekey_transit_key(self, key_name, new_key_name):
        """Rekey transit key"""
        try:
            response = self.client.secrets.transit.rekey(
                name=key_name,
                new_name=new_key_name
            )
            return response
        except Exception as e:
            print(f"Error rekeying key: {e}")
            return None

# Usage example
vault_rotation = VaultKeyRotation('http://localhost:8200', 'my-token')
vault_rotation.rotate_transit_key('my-encryption-key')
  • PKI - Infrastructure that manages key rotation
  • HSM - Device that facilitates key rotation
  • Key Escrow - System that complements key rotation
  • RSA - Algorithm that requires key rotation
  • AES - Algorithm that requires key rotation
  • CISO - Role that oversees key rotation
  • General Cybersecurity - Discipline that includes key rotation
  • Security Breaches - Incidents that require key rotation
  • Attack Vectors - Attacks that require key rotation
  • Incident Response - Process that includes key rotation
  • SIEM - System that monitors key rotation
  • SOAR - Automation that manages key rotation
  • EDR - Tool that protects key rotation
  • Firewall - Device that complements key rotation
  • VPN - Connection that requires key rotation
  • Dashboards - Visualization of key rotation metrics
  • Logs - Key rotation operation logs

References