The 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.Main
instance is available, but you can create your ownTAESPRNG
instance, 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.
You may use it in your projects by calling TAESPRNG.Main.FillRandom() overloaded methods or TAESPRNG.Main.FillRandomBytes().
See the class documentation.
The main idea of a CSPRNG is that its output is as safe as the cypher it is
based on.
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.
Just use TAESPRNG
when you need random input. Then go back to
your own code.
Feedback is welcome on our forum, as usual!