---
title: Reference Tokens 128-bit Entropy CSPRNG
impact: HIGH
impactDescription: prevents session hijacking via token guessing or brute-forcing
tags: tokens, entropy, csprng, session, security, kotlin
---

## Reference Tokens 128-bit Entropy CSPRNG

Opaque tokens (session IDs, API keys, reset tokens) must be generated using a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG) and contain enough entropy (randomness) to make them impossible to guess. 128 bits of entropy is the modern minimum standard.

**Incorrect (low entropy or predictable tokens):**

```kotlin
// VULNERABLE: Predicatable and low entropy (around 53 bits)
val id = (Math.random() * 1000000).toLong().toString()

// VULNERABLE: Short tokens (only 32 bits if using 4 hex chars)
val token = List(4) { ('a'..'z').random() }.joinToString("")

// INSECURE: Using non-secure Random
val random = java.util.Random()
val weakToken = BigInteger(130, random).toString(32)
```

**Correct (high entropy bytes from CSPRNG):**

```kotlin
import java.security.SecureRandom
import java.util.Base64

// 1. 128-bit minimum (16 bytes = 128 bits)
val secureRandom = SecureRandom()

fun generateSessionToken(): String {
    val bytes = ByteArray(16)
    secureRandom.nextBytes(bytes)
    return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes)
}

// 2. 256-bit for highly sensitive tokens (32 bytes)
fun generateApiKey(): String {
    val bytes = ByteArray(32)
    secureRandom.nextBytes(bytes)
    return "sk_" + Base64.getUrlEncoder().withoutPadding().encodeToString(bytes)
}

// 3. Using UUID (Standardized 128-bit random token)
val uuidToken = UUID.randomUUID().toString()
```

**Security Benchmarks:**

| Length | Entropy (approx) | Usage Recommendation |
| :--- | :--- | :--- |
| 16 bytes | 128 bits | **Minimum** for session tokens |
| 24 bytes | 192 bits | Strong |
| 32 bytes | 256 bits | **Recommended** for Long-lived API keys / Refresh tokens |

**Entropy Requirements:**
- Use `java.security.SecureRandom`.
- Ensure tokens are long enough. A Hex-encoded string needs twice as many characters as the raw bytes (e.g., 32 hex chars for 16 bytes).
- Do not include identifying information (like User IDs or IDs) in opaque reference tokens.

**Tools:** OWASP ZAP, Manual Review, SonarQube (S2245)
