%% fig-alt: "Key lifecycle from generation through destruction"
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22'}}}%%
flowchart LR
subgraph Lifecycle["Key Lifecycle"]
Gen[1. Generation<br/>Create secure key]
Dist[2. Distribution<br/>Deliver to devices]
Store[3. Storage<br/>Protect at rest]
Use[4. Usage<br/>Encrypt/decrypt]
Rotate[5. Rotation<br/>Replace periodically]
Destroy[6. Destruction<br/>Securely delete]
end
Gen --> Dist --> Store --> Use
Use --> Rotate --> Store
Use --> Destroy
style Gen fill:#27AE60,stroke:#2C3E50,color:#fff
style Destroy fill:#E74C3C,stroke:#2C3E50,color:#fff
1433 Key Management for IoT Devices
1433.1 Learning Objectives
By the end of this chapter, you will be able to:
- Design Key Lifecycle: Plan key generation, distribution, storage, rotation, and destruction
- Implement Secure Storage: Use hardware security modules, secure elements, and encrypted storage
- Apply Key Derivation: Generate multiple keys from a single master secret using KDFs
- Handle Provisioning: Securely inject keys during manufacturing or first-use enrollment
Key management is about the lifecycle of cryptographic keys - from birth (generation) to death (destruction). Strong encryption with weak key management is like having an unbreakable safe with the combination written on a sticky note.
Why it matters for IoT: The 2016 Mirai botnet compromised 600,000 IoT devices - not by breaking encryption, but because devices had hardcoded default credentials. Key management is often the weakest link in IoT security.
1433.2 The Key Lifecycle
1433.3 1. Key Generation
1433.3.1 Requirements
- Sufficient entropy: Use hardware random number generators (TRNG), not PRNGs seeded with predictable values
- Cryptographically secure: Keys must be indistinguishable from random
- Appropriate length: Match key size to security requirements
1433.3.2 IoT Key Generation Sources
| Source | Entropy Quality | Use Case |
|---|---|---|
| Hardware TRNG | Excellent | Production keys |
| Noise-based RNG | Good | Session keys |
| Software PRNG | Poor | Never for crypto |
| Timestamps/MACs | Terrible | Never use |
1433.3.3 Platform-Specific TRNG
// ESP32
uint32_t random_value = esp_random();
// STM32
HAL_RNG_GenerateRandomNumber(&hrng, &random_value);
// nRF52
nrf_drv_rng_rand(&random_buffer, size);1433.4 Never Generate Keys From Predictable Values
WRONG:
// MAC addresses are enumerable (2^24 combinations)
key = SHA256(device_mac_address);
// Serial numbers are sequential
key = SHA256(serial_number);
// Timestamps are predictable
key = SHA256(time(NULL));RIGHT:
// Use hardware TRNG
uint8_t key[32];
esp_fill_random(key, sizeof(key));1433.5 2. Key Distribution
1433.5.1 Manufacturing Provisioning
%% fig-alt: "Secure key provisioning during manufacturing"
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22'}}}%%
sequenceDiagram
participant HSM as HSM<br/>(Key Vault)
participant Prog as Programming<br/>Station
participant Device as IoT Device
Note over HSM: Master secrets stored<br/>in tamper-resistant hardware
HSM->>Prog: Generate device-unique key<br/>Signed certificate
Prog->>Device: Inject via JTAG/SWD<br/>(secure facility)
Device->>Device: Store in secure element<br/>or encrypted flash
Note over Device: Keys never leave secure storage<br/>after provisioning
1433.5.2 Provisioning Methods
| Method | Security | Complexity | Use Case |
|---|---|---|---|
| Factory injection | Highest | High | Mass production |
| First-use enrollment | High | Medium | Consumer devices |
| QR code + secure channel | Medium | Low | Onboarding |
| Hardcoded defaults | None | None | Never use |
1433.5.3 Certificate-Based Provisioning
For large deployments, use X.509 certificates:
- Device generates keypair locally (private key never leaves device)
- Device sends CSR (Certificate Signing Request) to CA
- CA signs certificate and returns to device
- Device stores certificate for future authentication
1433.6 3. Key Storage
1433.6.1 Storage Options (Ranked by Security)
| Storage Type | Security | Cost | Use Case |
|---|---|---|---|
| Secure Element | Highest | \[$ | High-value devices | | **TPM** | Very High | \] | Industrial IoT |
| Encrypted NVS | High | $ | Consumer IoT |
| Hardware key storage | High | $$ | Automotive, medical |
| Plain flash | None | - | Never use |
1433.6.2 Secure Element Integration
// ATECC608 example - key never leaves chip
atca_aes_encrypt(key_id, plaintext, ciphertext);
// Private key operations in secure element
atca_sign(SIGN_KEY_ID, digest, signature);1433.6.3 Encrypted Flash Storage
For devices without secure elements:
// ESP32 NVS encryption
nvs_open("keys", NVS_READWRITE, &handle);
// Keys encrypted with flash encryption key
// Derived from eFuse-protected master keyNever do:
// Hardcoded in source code
const char* API_KEY = "sk_live_abc123...";
// Plain text config file
echo "secret_key=abc123" > /etc/config.ini
// Environment variables visible in logs
export SECRET_KEY="abc123"Always: - Use hardware secure storage when available - Encrypt keys at rest with device-unique key - Derive runtime keys, don’t store them permanently
1433.7 4. Key Derivation
Use Key Derivation Functions (KDFs) to generate multiple keys from a single master secret:
1433.7.1 HKDF (HMAC-based Key Derivation Function)
%% fig-alt: "HKDF deriving multiple keys from master secret"
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22'}}}%%
flowchart TB
Master[Master Secret<br/>32 bytes]
subgraph HKDF["HKDF-SHA256"]
Extract[Extract<br/>Salt + IKM]
Expand[Expand<br/>PRK + Info]
end
subgraph Keys["Derived Keys"]
K1[Encryption Key<br/>info="encrypt"]
K2[MAC Key<br/>info="mac"]
K3[Session Key<br/>info="session_123"]
end
Master --> Extract --> Expand
Expand --> K1
Expand --> K2
Expand --> K3
style Master fill:#2C3E50,stroke:#16A085,color:#fff
style Keys fill:#16A085,stroke:#2C3E50
1433.7.2 Benefits of Key Derivation
- Single provisioning: Inject one master key, derive others as needed
- Key separation: Compromise of one derived key doesn’t expose others
- Unlimited keys: Generate session keys, per-message keys, etc.
- Reproducible: Same inputs always produce same outputs
1433.7.3 Example: Deriving Session Keys
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes
master_key = b"device_master_secret_32_bytes..."
session_id = b"session_20240115_143052"
# Derive unique session key
hkdf = HKDF(
algorithm=hashes.SHA256(),
length=32,
salt=None,
info=b"session_encryption_" + session_id
)
session_key = hkdf.derive(master_key)1433.8 5. Key Rotation
1433.8.1 Why Rotate Keys?
- Limit exposure: If key is compromised, limit damage window
- Forward secrecy: Old communications can’t be decrypted with new key
- Compliance: Many standards require periodic rotation
1433.8.2 Rotation Strategies
| Strategy | Frequency | Trigger | Use Case |
|---|---|---|---|
| Time-based | Daily/monthly | Timer | Session keys |
| Usage-based | After N uses | Counter | Encryption keys |
| Event-based | On compromise | Detection | All keys |
| Hybrid | Whichever first | Both | Best practice |
1433.8.3 Automated Rotation Example
# Check if key needs rotation
key_created = get_key_creation_time()
key_age = datetime.now() - key_created
max_age = timedelta(days=30)
if key_age > max_age:
# Generate new key
new_key = generate_key()
# Re-encrypt data with new key (gradual migration)
migrate_encrypted_data(old_key, new_key)
# Destroy old key after migration
secure_delete(old_key)1433.9 6. Key Destruction
1433.9.1 Secure Deletion Requirements
- Overwrite memory: Don’t just free() - overwrite with zeros/random
- Multiple passes: For flash storage, overwrite multiple times
- Verify destruction: Confirm data is unrecoverable
- Audit trail: Log destruction (but not the key itself)
1433.9.2 Platform-Specific Secure Deletion
// Secure key zeroization
void secure_zero(void* ptr, size_t len) {
volatile unsigned char* p = ptr;
while (len--) *p++ = 0;
}
// ESP32: Erase NVS key
nvs_erase_key(handle, "device_key");
nvs_commit(handle);Flash memory uses wear-leveling, which may leave old data in spare blocks. For high-security applications:
- Encrypt keys before storing in flash
- Store keys only in secure elements
- Use full-disk encryption with hardware key
1433.10 Key Management Architecture
%% fig-alt: "Hierarchical key management architecture"
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22'}}}%%
flowchart TB
subgraph Cloud["Cloud Key Management"]
MasterHSM[Master Key<br/>HSM Protected]
end
subgraph Device["IoT Device"]
DeviceKey[Device Identity Key<br/>Secure Element]
SessionKey[Session Keys<br/>Derived, Ephemeral]
DataKey[Data Encryption Key<br/>Encrypted Storage]
end
MasterHSM -->|"Provisions<br/>(manufacturing)"| DeviceKey
DeviceKey -->|"Derives"| SessionKey
DeviceKey -->|"Protects"| DataKey
style MasterHSM fill:#E74C3C,stroke:#2C3E50,color:#fff
style DeviceKey fill:#E67E22,stroke:#2C3E50,color:#fff
style SessionKey fill:#16A085,stroke:#2C3E50,color:#fff
style DataKey fill:#16A085,stroke:#2C3E50,color:#fff
1433.11 Knowledge Check
A developer generates encryption keys using SHA256(device_serial_number). What is the security problem?
Options:
- SHA-256 is too slow for key generation
- Serial numbers are sequential/predictable, allowing attackers to pre-compute all possible keys
- SHA-256 output is too short for encryption keys
- This approach uses too much battery
Correct: B
Serial numbers are sequential and predictable. An attacker can enumerate all possible serial numbers and pre-compute the corresponding keys. For example, if serial numbers are 8-digit numbers (00000001-99999999), there are only 100 million possible keys - trivially computable. Keys must be generated from high-entropy sources like hardware TRNGs.
Your IoT device stores an AES encryption key in flash memory at a known address. What is the primary security concern?
Options:
- Flash memory is too slow for encryption operations
- An attacker with physical access can extract the key using JTAG/SWD or flash dumping
- AES keys are too large for flash storage
- Flash memory corrupts keys over time
Correct: B
Plain-text keys in flash can be extracted via physical attacks (JTAG debugging, flash chip removal, logic analyzer). Solutions include: secure elements that never expose keys, encrypted flash with eFuse-protected master key, or secure boot that validates firmware before releasing keys.
1433.12 Best Practices Summary
- Generate keys from hardware TRNG - Never from predictable values
- Provision keys securely - Factory injection or first-use enrollment
- Store keys in secure elements - Or encrypted with device-unique key
- Use key derivation - One master key derives all others
- Rotate keys regularly - Limit exposure from potential compromise
- Destroy keys securely - Overwrite, don’t just delete
- Audit key operations - Log access, rotation, destruction
- Plan for compromise - Have revocation and recovery procedures
1433.13 Summary
- Key management is often the weakest link - Strong encryption means nothing with poor key handling
- Generate keys from true randomness - Hardware TRNGs, never predictable values
- Store keys securely - Secure elements > encrypted flash > never plain text
- Use key derivation - HKDF generates multiple keys from one master secret
- Rotate keys regularly - Limit the window of exposure if compromised
- Destroy keys securely - Overwrite memory, don’t just delete references
1433.14 What’s Next
Continue to Interactive Encryption Tools to explore calculators and simulators that help you understand encryption strength, compare algorithms, and make informed security decisions.