AES-256 based Cryptographically Secure Pseudo-Random Number Generator (CSPRNG)
Everyone knows about the pascal random()
It returns some numbers, using a linear congruential generator, with a multiplier of 134775813, in its Delphi implementation.
It is fast, but not really secure. Output is very predictable, especially if you forgot to execute the RandSeed() procedure.
In real world scenarios, safety always requires random numbers, e.g. for
The less predictable, the better.
We just included a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG) into our SynCrypto.pas unit.
TAESPRNG class would use real system entropy to generate
a sequence of pseudorandom bytes, using AES-256, so returning highly
TAESPRNG class is implemented as such:
- It would gather entropy using dedicated OS API, i.e. the CryptGenRandom API under Windows or /dev/urandom - /dev/random on Linux/POSIX systems; and since we are paranoid, we XOR some entropy hash (retrieved e.g. directly from RDTSC and other system variables) to those OS values - so even if the API is compromised, we try to have some changing input;
- This entropy (256 bytes of password, 16 bytes of salt) would be hashed using safe PBKDF2-HMAC-SHA256 key derivation function (256 iterations by default) to setup the secret key of an AES-256 cypher, and set a counter (CTR) initial value by applying this AES-256 to the salt;
- Each time some output is to be generated, AES-256 is applied to the CTR to produce 16 bytes (2^128 bits) of pseudorandom data;
- The CTR is incremented after each 16-byte block; AES being a block cipher, it is a permutation of the space of block values: as such, it won't ever output twice the same 16-byte block, so you can generate 2^128 blocks, i.e. 2^132 bytes before the CTR overflows;
- The AES-256 cypher is re-seeded from entropy on a regular basis (after some bytes are generated), to avoid potential attacks on backward or forward security;
- The implementation is thread-safe, a shared
TAESPRNG.Maininstance is available, but you can create your own
TAESPRNGinstance, with tuned parameters (number of PBKDF2 counts or automatic re-seeding number of bytes);
- The level of security would be the same on all platforms, since OS is used only for entropy, but an unique CSPRNG algorithm would actually generate the data - even a compromised system (older CryptGenRandomAPI had known weaknesses, or you could imagine some plot-based undocumented backdoor) may produce safe enough output;
- It would use AES-NI or Padlock hardware acceleration, if available.
See the class documentation.
The main idea of a CSPRNG is that its output is as safe as the cypher it is
Using AES-256, and initial PBKDF2 key derivation of OS-gathered entropy, implements a very good randomness extractor.
Last but not least, especially if your CPU supports AES-NI (which is very likely on a server), performance would be very high.
TAESPRNG when you need random input. Then go back to
your own code.
Feedback is welcome on our forum, as usual!