Generating Cryptographically Secure Tokens

Generating cryptographically secure tokens

Here is the correct solution:

$token = bin2hex(openssl_random_pseudo_bytes(16));

# or in php7
$token = bin2hex(random_bytes(16));

Generating cryptographically secure authentication tokens

Based on the feedback from the other answers to this question, additional research, and offline discussions, here is what we ended up doing...

It was pointed out pretty quickly that the interaction model here is essentially exactly the same as the model used by Forms Authentication in ASP.NET when a "remember me" checkbox is checked. It's just not a web browser making the HTTP requests. Our "ticket" is equivilant to the cookie that Forms Authentication sets. Forms Authentication uses essentially an "encrypt some data with a secret key" approach by default.

In our login web service, we use this code to create a ticket:

string[] userData = new string[4];

// fill the userData array with the information we need for subsequent requests
userData[0] = ...; // data we need
userData[1] = ...; // other data, etc

// create a Forms Auth ticket with the username and the user data.
FormsAuthenticationTicket formsTicket = new FormsAuthenticationTicket(
1,
username,
DateTime.Now,
DateTime.Now.AddMinutes(DefaultTimeout),
true,
string.Join(UserDataDelimiter, userData)
);

// encrypt the ticket
string encryptedTicket = FormsAuthentication.Encrypt(formsTicket);

Then we have an operation behavior attribute for the WCF services that adds an IParameterInspector that checks for a valid ticket in the HTTP headers for the request. Developers put this operation behavior attribute on operations that require authentication. Here is how that code parses the ticket:

// get the Forms Auth ticket object back from the encrypted Ticket
FormsAuthenticationTicket formsTicket = FormsAuthentication.Decrypt(encryptedTicket);

// split the user data back apart
string[] userData = formsTicket.UserData.Split(new string[] { UserDataDelimiter }, StringSplitOptions.None);

// verify that the username in the ticket matches the username that was sent with the request
if (formsTicket.Name == expectedUsername)
{
// ticket is valid
...
}

How can I generate a secure and unique token to use in an online ticket service?

Unique token? install paragonie/constant_time_encoding

Base64UrlSafe::encode(random_bytes(9))

  • In MySQL, an INTEGER(11) UNSIGNED primary key can hold about 4 billion rows. This is equal to 32 bits.
  • If you generate 9 raw bytes from a cryptographically secure pseudorandom number generator (72 bits of possible values), then base64 the result, you will end up with a 12 character identifier.
  • 72 bits of possible values means a 50% chance of collision at 2**36 records, according to the birthday problem.

This means you have a 50% chance of only two duplicate random values after about 69 billion records (a far cry beyond your 4 billion storage capacity). This means that you will almost never have a collision. You should still make sure every selector you generate is unique before inserting a new one, of course.

source


Note: this is just to answer the question, scroll down for more approach.

Generate cryptographically secure tokens with built-in expiration period

Why not use a JWT in it's simplest form with not befor and not after time defined , you can leave out the claims... JWT fits the bill completely here..

How do I generate a cryptographically secure random number to use for bearer tokens?

For Vapor you can generate a token like so:

[UInt8].random(count: 32).base64

That will be cryptographically secure to use. You can use it like in this repo

What makes a string / token cryptographically secure?


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().

How do I generate a cryptographically secure alphanumeric string in Python?

Use PyCrypto, which implements a cryptographically secure version of python's random module. Google App Engine offers this as a library you can include in your App Engine project by adding the following to app.yaml:

libraries:
- name: pycrypto
version: "2.6"

PyCrypto is also available outside GAE as a python library.

You can then generate a 32-character alphanumeric string with

from Crypto.Random import random

def generate_auth_token():
""" Generate a 32-char alnum string. 190 bits of entropy. """
alnum = ''.join(c for c in map(chr, range(256)) if c.isalnum())
return ''.join(random.choice(alnum) for _ in range(32))

ASP.Net - Generating Secure Tokens

A random authentication token could be enough depending on the kind of architecture you have.

Or you could use GUIDs, ... There are a lot of possibilities, here is one:

When the user authenticates, generate a random token, add it into a cookie on the user system and into the database. When the user comes back, the unique random token is searched in the database so you can establish the link between the random token and the user. Tada !



Related Topics



Leave a reply



Submit