First, you should not implement your own CSPRNG user space. The operating system on which PHP 5 is installed already has CSPRNG, and you should use this for all your chance if you donβt know that you can use it, or performance is a problem. You should use random_int() , random_bytes() or openssl_random_pseudo_bytes() .
However, if you must implement the CSPRNG user space, this can be done simply by using the AES library (EG: libsodium) and encrypting the counter. Psuedocode will be:
Uint-128 n = 0; while true: output = AES-ECB(key, n); n++;
The AES key in this case needs enough entropy to withstand a complex attack, or the security of your CSPRNG user space falls apart, of course. The key may be the bcrypt() password provided by the user.
Provided that your counter, presented as a 128-bit unsigned integer, is always unique, you will always get a unique result each time the generator is "seeded" with a new counter. If it is seeded with a previously used counter, but with a different key, then the output will also be different. The best scenario is to change the key and the changing counter each time the generator is called.
You may be tempted to use a high-precision timestamp, for example, accurate to the microsecond, in your counter. This is normal, except that you risk someone or manipulate the system clock with something. Thus, if the watch can be manipulated, then the CSPRNG generator can be compromised. It is best to provide a new key every time you call the generator, and start encryption with 128-bit zero.
Also note that we use ECB mode with AES. Do not worry. The ECB has problems preserving the structure in ciphertext that provides plaintext. In general, you should not use ECB mode. However, with 128-bit data, you will only encrypt one ECB, so there will be no leakage of structured data. An ECB is preferable to a CTR for the CSPRNG user space, as you do not need to track the key, counter object, and data that needs to be encrypted. Only a key and data are required. Just make sure you never encrypt more than 128 bits of data, and you don't need more than 1 block.
Can CSPRNG be seeded?
Yes, and he must always be sown. If you look at your GNU / Linux operating system, you will probably notice the file in /var/lib/urandom/random-seed . When the operating system shuts down, it creates this file from CSPRNG. At the next boot, this file is used to seed the CSPRNG kernel to prevent reuse of the previous state of the generator. Each time you disconnect, this file should change.
If it can be seeded, will the output be deterministic (same random result, given the same seed)?
Yes. Provided the same seed, key, etc. The output is deterministic, so the output will be the same. If one of your variables changes, the result will be different. This is why the generator must be programmed with every call.