Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What makes a string / token cryptographically secure?

If you need to generate a string / token to authenticate future requests (e.g. an API key, an email confirmation URL, etc.), what factors should be considered?

In particular

  • What makes the string "secure" / "very hard to guess"?
  • How is the "security amount" measured / estimated?
  • What are the main standards out there?

A practical example

Let's take these two output strings from NodeJS.

String 1 (through Node crypto)

var crypto = require('crypto');
crypto.randomBytes(48, function (ex, buf) {
  console.log(buf.toString('hex'));
});

String 2 (through Node UUID)

var uuid = require('node-uuid');
console.log(uuid.v4());

Based on the concepts outlined above, which one would be more secure and why?

Also, please feel free to suggest any good introductory material on the topic, as I couldn't easily find articles about this online.

like image 547
Pensierinmusica Avatar asked Aug 12 '15 13:08

Pensierinmusica


People also ask

Is random Randbytes cryptographically secure?

crypto.randomBytes(size[, callback]) Generates cryptographically strong pseudo-random data. The size argument is a number indicating the number of bytes to generate. This means that the random data is secure enough to use for encryption purposes.

Is Nodejs crypto secure?

Node. js is one such technology that developers use for web application development. It is designed to be completely secure.


1 Answers

What makes the string "secure" / "very hard to guess"?

A string or token cannot be cryptographically secure, because it is static.

The notion of a cryptographically secure (pseudo) random number generator (CS(P)RNG) describes that the produced numbers are not predictable. It's a property of the procedure and not of the individual numbers.

How is the "security amount" measured / estimated?

That depends on the randomness sources that are used, because some of them are a black box. You can generate a lot of randomness and see if you find some patterns in there. There are some test suites available, but then you have to think about your application and how fast you need those random numbers. It is possible that requesting a lot of randomness depletes the pool and then produces insufficiently random numbers.

What are the main standards out there?

Use your system's/framework's designated cryptographically secure randomness sources. Node.js' crypto.randomBytes() is one of those if you want to trust the documentation.

A practical example

node-uuid uses crypto.randomBytes() internally, so there is essentially the same randomness strength behind it, but it will fallback to Math.random() if crypto.randomBytes() is not available. Math.random() is not cryptographically secure. If you want to have a cryptographically secure random values in the browser, you will need to query Web Crypto API's getRandomValues().

like image 176
Artjom B. Avatar answered Oct 14 '22 03:10

Artjom B.