I am wondering if there is a way to generate a Cryptographic Nonce using OpenSSL or Crypto++ libraries. Is there anything more to it than just generating a set of random bytes using autoseeded pools?
- AFAIAA it's just a pseudo-random sequence of bytes. Of course you'll want to seed the sequence generator with a real random source.Richard Hodges– Richard Hodges2015-05-08 14:56:36 +00:00Commented May 8, 2015 at 14:56
- @RichardHodges: Thanks for your reply. A nonce is supposed to sequential in the sense that it must be guaranteed to be generated only once in a "session". Wouldn't there be any additional requirements or things that need to be done for a nonce as opposed to generating an IV using a RNG?SkypeMeSM– SkypeMeSM2015-05-08 15:20:45 +00:00Commented May 8, 2015 at 15:20
- 1@SkypeMeSM - Also see RandomNumberGenerator on the Crypto++ wiki; and Random Numbers on the OpenSSL wiki. Also, NIST SP800-38C and SP800-38D has a couple of methods for creating nonces because CCM and GCM uses them. Also see the documentation on CTR mode. I seem to recall a discussion there, too.jww– jww2015-05-08 17:28:00 +00:00Commented May 8, 2015 at 17:28
- Thanks @jww. The NIST recommendations will be very helpful. I will check it out.SkypeMeSM– SkypeMeSM2015-05-08 17:42:20 +00:00Commented May 8, 2015 at 17:42
3 Answers
I am wondering if there is a way to generate a cryptographic nonce using OpenSSL or Crypto++ libraries.
Crypto++:
SecByteBlock nonce(16); AutoSeededRandomPool prng; prng.GenerateBlock(nonce, nonce.size()); OpenSSL:
unsigned char nonce[16]; int rc = RAND_bytes(nonce, sizeof(nonce)); unsigned long err = ERR_get_error(); if(rc != 1) { /* RAND_bytes failed */ /* `err` is valid */ } /* OK to proceed */ Is there anything more to it than just generating a set of random bytes using autoseeded pools?
A nonce is basically an IV. Its usually considered a public parameter, like an IV or a Salt.
A nonce must be unique within a security context. You may need a nonce to be unpredictable, too.
Uniqueness and unpredictability are two different properties. For example, a counter starting at 0000000000000000 is unique, but its also predictable.
When you need both uniqueness and unpredictability, you can partition the nonce into a random value and a counter. The random value will take up 8 bytes of a 16 byte nonce; while the counter will take up the remaining 8 bytes of a 16 byte nonce. Then you use an increment function to basically perform i++ each time you need a value.
You don't need an 8-8 split. 12-4 works, as does 4-12. It depends on the application and the number of nonces required before rekeying. Rekeying is usually driven by plain text byte counts.
16-0 also works. In this case, you're using random values, avoiding the counter, and avoiding the increment function. (The increment function is basically a cascading add).
NIST SP800-38C and SP800-38D offer a couple of methods for creating nonces because CCM and GCM uses them.
Also see What are the requirements of a nonce? on the Crypto Stack Exchange.
Comments
No. If the nonce is large enough then an autoseeded DRBG (deterministic random bit generator - NIST nomenclature) is just fine. I would suggest a nonce of about 12 bytes. If the nonce needs to be 16 bytes then you can leave the least significant bits - most often the rightmost bytes - set to zero for maximum compatibility.
Just using the cryptographically secure random number generators provided by the API should be fine - they should be seeded using information obtained from the operating system (possibly among other data). It never hurts to add the system time to the seed data just to be sure.
Alternatively you could use a serial number, but that would require you to keep some kind of state which may be hard across invocations. Beware that there are many pitfalls that may allow a clock to repeat itself (daylight saving, OS changes, dead battery etc. etc.).
It never hurts to double check that the random number generator doesn't repeat for a large enough output. There have been issues just with programming or system configuration mistakes, e.g. when a fix after a static code analysis for Debian caused the OpenSSL RNG not to be seeded at all.
Comments
You need a unique number for each nonce. You can use either a serial number or a random number. To help ensure uniqueness, it is common, though not required, to add a timestamp to the nonce. Either passing the timestamp as a separate field or concatenating it with the nonce. Sometimes information such as IP addresses and process IDs are also added.
When you use a serial number, you don't need to worry about skipping numbers. That's fine. Just make sure you never repeat. It must be unique across restarts of your software. This is one place where adding a timestamp can help. Because time-in-millis+serial-number is almost certainly unique across restarts of the server.
For the pseudo random number generator, anyone should be fine. Just make sure that you use a sufficiently large space to make the chances of getting a duplicate effectively impossible. Again, adding time will reduce the likelihood of you getting duplicates as you'll need to get the same random number twice in the same millisecond.
You may wish to hash the nonce to obscure the data in it (eg: process ID) though the hash will only be secure if you include a secure random number in the nonce. Otherwise it may be possible for a viewer of the nonce to guess the components and validate by redoing the hash (ie: they guess the time and try all possible proc IDs).