# Insecure Key Derivation via Low PBKDF2 Iteration Count

Language: Python
Severity: High
CWE: CWE-916

## Source
4

## Flow
4-6-7

## Sink
7

## Vulnerable Code
```python
import hashlib
import os
from base64 import b64encode

def secure_iot_device_pairing(device_mac, owner_pin):
    salt = os.urandom(16)
    iterations = 100
    derived_key = hashlib.pbkdf2_hmac('sha256', owner_pin.encode(), salt, iterations, dklen=32)
    pairing_token = b64encode(salt + derived_key).decode('utf-8')
    store_device_credential(device_mac, pairing_token)
    return {'device_id': device_mac, 'pairing_token': pairing_token, 'status': 'paired'}

def store_device_credential(mac, token):
    with open(f'/var/iot/devices/{mac}.cred', 'w') as f:
        f.write(token)
```

## Explanation

The code uses only 100 PBKDF2 iterations to derive cryptographic keys from PIN codes, which is far below the recommended minimum of 600,000 iterations for PBKDF2-HMAC-SHA256 (OWASP 2023). This makes the derived keys extremely vulnerable to brute-force and GPU-accelerated attacks, allowing attackers who capture pairing tokens to rapidly crack the owner PINs and compromise device security.

## Remediation

The fix increases the PBKDF2 iteration count from 100 to 600,000, which is the OWASP 2023 recommended minimum for PBKDF2-HMAC-SHA256. This makes brute-force and GPU-accelerated attacks computationally infeasible, even against short PIN codes, by dramatically increasing the time required to test each candidate password.

## Secure Code
```python
import hashlib
import os
from base64 import b64encode

def secure_iot_device_pairing(device_mac, owner_pin):
    salt = os.urandom(16)
    iterations = 600000
    derived_key = hashlib.pbkdf2_hmac('sha256', owner_pin.encode(), salt, iterations, dklen=32)
    pairing_token = b64encode(salt + derived_key).decode('utf-8')
    store_device_credential(device_mac, pairing_token)
    return {'device_id': device_mac, 'pairing_token': pairing_token, 'status': 'paired'}

def store_device_credential(mac, token):
    with open(f'/var/iot/devices/{mac}.cred', 'w') as f:
        f.write(token)
```
