4

I have a site which uses nonce. Everything works well. But how long or complex should be the nonce.

My little nonce maker is just this:

let generateNonce = (length = 32) => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let nonce = '';
  for (let i = 0; i < length; i++) 
    nonce += chars.charAt(Math.floor(Math.random() * chars.length));
  return nonce;
};

A call of generateNonce() returns something like hERnT30lr0G3Hw4b5eQCjuC423a3PcBl.

32 characters of numbers, lower and upper case letters. Is this complex enough or even too long?

tom
  • 9,550
  • 6
  • 30
  • 49
  • See the CSP spec section at https://w3c.github.io/webappsec-csp/#security-nonces, which says nonce values *“should be at least 128 bits long (before encoding), & should be generated via a cryptographically secure random number generator”*. Your `hERnT30lr0G3Hw4b5eQCjuC423a3PcBl` has more than 128 bits, so that”s fine. But Math.random() isn’t cryptographically secure. See the explanations at https://stackoverflow.com/a/5651854/441757 & https://security.stackexchange.com/q/181580/86150. Use Crypto.getRandomValues() https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues instead. – sideshowbarker Sep 07 '19 at 00:28
  • @sideshowbarker thank you. Very informative and useful links. Could you post it as an answer please. – tom Sep 07 '19 at 07:33
  • OK — added as an answer – sideshowbarker Sep 07 '19 at 09:18

2 Answers2

2

See the CSP spec section at https://w3c.github.io/webappsec-csp/#security-nonces, which says:

[nonce values] should be at least 128 bits long (before encoding), and should be generated via a cryptographically secure random number generator

The question’s hERnT30lr0G3Hw4b5eQCjuC423a3PcBl value is more than 128 bits, so that’s OK.

But Math.random() isn’t cryptographically secure; https://stackoverflow.com/a/5651854/441757 and https://security.stackexchange.com/q/181580/86150. Use Crypto.getRandomValues instead.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
1

With the help of @sideshowbarker the nonce generator could be like this (nodejs)

// require nodes native crypto module
const crypto = require('crypto');

// create 128 bit nonce synchronously
const nonce = crypto.randomBytes(16).toString('hex');

output = 1e31b6130c5be9ef4cbab7eb38df5491

crypto.randomBytes(size[, callback])

Generates cryptographically strong pseudo-random data. The size argument is a number indicating the number of bytes to generate.

tom
  • 9,550
  • 6
  • 30
  • 49