Skip to content

davnicwil/crypto

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 

Repository files navigation

crypto

generic, reusable cryptography services

services

RandomStringGenerator

.generate() - generates a random String

Implementations

RandomStringGeneratorImpl

constructors

RandomStringGeneratorImpl(Integer length) - length is the desired length of the generated Strings

about

This implementation generates cryptographically secure random Strings suitable for use as access tokens (assuming sufficient length).

The generated Strings are alphanumeric, using both upper and lower case letters from the English alphabet.

Each String is generated using a new Random instance, which is only used to generate one String and then never reused.

A Random instance by does not not generate cryptographically secure sequences. With sufficient samples an attacker can work out the seed and predict future values, and by default an instance is seeded with the current System timestamp, which puts it in a tractable range for brute force attacks, too.

This implementation mitigates against these weaknesses in two ways.

Firstly, because each Random is used only once to generate one String, analysing one String and cracking the Random seed used to generate it does not give you any information you can use to guess other Strings generated in the past or future.

Secondly, arbitrary Strings cannot be guessed using brute force timing-based attacks because each Random instance is seeded with a real random number composed by adding together a number generated by a SecureRandom instance (which draws randomness from the underlying OS and is cryptographically secure) and the number of calls to .generate() which have so far occurred (this is more of a why-not-it's-cheap source of noise to the already extremely secure seed).

Why not just use SecureRandom to pick all the random characters, instead of seeding a Random instance with it and using that? Good question! There's a performanceTest() method in the test class which showed me a 25x performance increase doing the latter rather than the former. If you're going to be using this a lot, for example regenerating access tokens on every api call, or something, then that really matters (imagine running a single server rather than a cluster of 25 at scale :-), and if my understanding is correct, there's no practical loss of security by doing it.

Because of the use of SecureRandom, a RandomStringGeneratorImpl instance is expensive to initialise, so it is preferable (and perfectly secure) to construct an instance once and reuse it as much as possible.

Unit tests

There is an abstract base unit test class for generate() that new implementations can piggy-back on for zero effort testability - only limitation is it assumes an implementation with a constructor taking an Integer length argument, for the length of string to produce.

It tests

  • Strings of the correct length are produced

  • Strings are sufficiently random - i.e. no duplicates are produced over a large-enough sample size (configurable in the contructor depending on your use-case).

  • Performance test - how quickly are 1 million Strings of length 128 produced. This is useful for tweaking the performance of your implementation, once you know it works.

About

generic, reusable cryptography services

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages