Cryptographically Secure Random Numbers in Unix-Linux
https://x.com/i/grok/share/wEuX4JkCpt7EtAEm1wiuW9tb4
The default random library in Python (and in most other programming languages) is not secure for generating private keys.
import random
def insecure_private_key():
return hex(random.getrandbits(256))[2:]
# cd6fd587101f73ab881fe377b5d87343a4e094dc8dcaa3cc54aef47670e1bfac
The random module uses the Mersenne Twister Algorithm, which is deterministic, which means it can be predicted if the seed is known. This makes it vulnerable to state recovery attacks.
For having secure random numbers, you need to get it either from /dev/urandom file in or by getrandom() syscall (in Unix/Linux).
All options I could find are:
1. From /dev/urandom file
1. read directly
2. read indirectly
1. by os.urandom(32) who reads from dev/urandom
2. by random.SystemRandom who reads from os.urandom(32)
3. by secrets who built on top of random.SystemRandom
2. From getrandom() syscall (Linux)
1. provides direct, secure access to the kernel entropy pool without going through the file system.
2. considered more secure and reliable than dev/urandom
3. From the Hardware
1. Hardware-Based Randomness
4. From ANU Quantum Random Numbers (archived)
1. e.g. curl "https://qrng.anu.edu.au/API/jsonI.php?length=32&type=uint8"
2. They offer real quantum random numbers for anyone on the internet. They rate limit by 1 per minute.
The /dev/urandom is a cryptographically secure pseudorandom number generator (CSPRNG).
How does dev/urandom generated? How frequently does it change?
def secure_private_key():
return secrets.token_bytes(32).hex()
# cc9e7116e58c321f11c0116a5b34f883c730e69cae8ccb24b0c8b37046ea2f51
| Aspect | random |
secrets |
|---|---|---|
| 🔒 Security | ❌ Not secure — predictable if seed/state is known | ✅ Secure — uses CSPRNG, safe for cryptographic use |
| 🧠 Predictability | ❌ Predictable (Mersenne Twister algorithm) | ✅ Unpredictable |
| 🕹️ Use Case | Simulations, games, statistics, shuffling, sampling | Generating tokens, passwords, keys, secure IDs |
| 🐢 Performance | ✅ Faster (no need for entropy source) | ❌ Slower (due to system entropy and security checks) |
| 📚 Functionality | Rich API: shuffle(), gauss(), choice(), etc. |
Minimal API: choice(), token_bytes(), randbelow()
|
| 🧪 Repeatability | ✅ Reproducible with random.seed()
|
❌ No reproducibility — by design |
| 🧬 Determinism | ✅ Deterministic | ❌ Non-deterministic |
| 🧯 Resilience to Attack | ❌ Vulnerable to state-recovery and prediction attacks | ✅ Resists all known attacks (via OS CSPRNG) |
| 🕰️ Availability | Available since early Python versions | Introduced in Python 3.6 (2016) |
| 🏗️ Underlying Source | Mersenne Twister PRNG | OS-level CSPRNG (/dev/urandom, CryptGenRandom, etc) |
Also see: - Private Key - A Very Large Random Number (archived) - How to Generate Secure Random Numbers in Various Programming Languages - Paragon Initiative Enterprises Blog (archived) - Myths about devurandom (archived)
- ANU Quantum Random Numbers (archived)
- Hardware-Based Randomness
- How to Generate Secure Random Numbers in Various Programming Languages - Paragon Initiative Enterprises Blog (archived)
- Mersenne Twister Algorithm
- Myths about devurandom (archived)
- Private Key - A Very Large Random Number (archived)
- cryptographically secure pseudorandom number generator (CSPRNG)
- state recovery attack