# Hardcoded Cryptographic Key in Fernet Encryption

Language: Python
Severity: Critical
CWE: CWE-798

## Source
5

## Flow
5-6-7-8

## Sink
6

## Vulnerable Code
```python
from cryptography.fernet import Fernet
import boto3

def encrypt_iot_telemetry(device_id, sensor_data):
    MASTER_KEY = b'zK8vQ2mP9xR4wN7jL3hF6tY1sC5bV0aE8dG2nM4pU6q='
    cipher = Fernet(MASTER_KEY)
    payload = f"{device_id}|{sensor_data['temp']}|{sensor_data['humidity']}"
    encrypted_payload = cipher.encrypt(payload.encode())
    s3_client = boto3.client('s3')
    s3_client.put_object(Bucket='iot-telemetry-vault', Key=f'device_{device_id}.enc', Body=encrypted_payload)
    return encrypted_payload.decode()
```

## Explanation

The code contains a hardcoded Fernet encryption key directly embedded in the source code (line 5), which is then used to initialize the cipher (line 6). This compromises the confidentiality of all encrypted telemetry data since anyone with access to the source code or binary can extract the key and decrypt all stored IoT sensor data in the S3 bucket.

## Remediation

The fix removes the hardcoded cryptographic key and replaces it with a secure retrieval mechanism using AWS Secrets Manager. The encryption key is now fetched at runtime from a managed secrets store, ensuring it never appears in source code and can be rotated without code changes.

## Secure Code
```python
from cryptography.fernet import Fernet
import boto3
import os


def get_encryption_key():
    """Retrieve encryption key from AWS Secrets Manager."""
    secret_name = os.environ.get('IOT_ENCRYPTION_KEY_SECRET', 'iot-telemetry-encryption-key')
    region = os.environ.get('AWS_REGION', 'us-east-1')
    
    client = boto3.client('secretsmanager', region_name=region)
    response = client.get_secret_value(SecretId=secret_name)
    return response['SecretString'].encode()


def encrypt_iot_telemetry(device_id, sensor_data):
    encryption_key = get_encryption_key()
    cipher = Fernet(encryption_key)
    payload = f"{device_id}|{sensor_data['temp']}|{sensor_data['humidity']}"
    encrypted_payload = cipher.encrypt(payload.encode())
    s3_client = boto3.client('s3')
    s3_client.put_object(Bucket='iot-telemetry-vault', Key=f'device_{device_id}.enc', Body=encrypted_payload)
    return encrypted_payload.decode()
```
