Helper class to simplify the use of Bouncy Castle's scrypt implementation for salted password hashing.

Mark George authored on 22 Nov 2018
src Added example and README. 5 years ago
.gitignore Initial commit. 5 years ago
README.md Fixed header problem in README. 5 years ago
build.gradle Initial commit. 5 years ago
README.md

BouncyScrypt

A facade for salted password hashing with scrypt using Bouncy Castle.

Generates output that is in a format similar to Modular Crypt Format (MCF). The output includes the following fields (separated by a $ character):

  • The work factors that were used bit-packed into a single Integer.
  • The Base64 encoded generated salt.
  • The Base64 encoded derived hash.

The result looks like:

The salts are generated using Java's SHA1PRNG secure psuedo-random number generator.

The standard scrypt work factors are used:

* N = 16384
* r = 8
* p = 1

Both the generated salt and the derived hash (`dkLen`) are 64 bytes.  The generated output is 186 characters.

#API

```java
// generate a hash
public static CharBuffer hash(CharSequence password)

// check a password against a hash
public static boolean check(CharSequence mcfHash, CharSequence password)

#Usage

The API uses CharSequence objects as input and CharBuffer objects as output. This gives us a couple of choices:

  • Use String objects for simplicity. The downside of String objects is that they are immutable meaning that we can't overwrite the sensitive data when we are finished with it.

  • Use char[] and CharBuffer objects so that we can overwrite the data when we are finished with it.

Simple mode (using Strings)

Generating a hash:

String password = "testing123";
String hash = ScryptHelper.hash(password).toString();

Checking a password against a hash:

boolean isValid = ScryptHelper.check(hash, password);

Paranoid mode (using char[] and CharBuffer objects)

Generating a hash:

char[] password = "testing123".toCharArray();
CharBuffer cb = CharBuffer.wrap(password);
CharBuffer hash = ScryptHelper.hash(cb);

Checking a hash against a password:

boolean isValid = ScryptHelper.check(hash, cb);

Overwriting the sensitive data once you have finished with it:

Arrays.fill(password, '0');
Arrays.fill(hash.array(), '0');

Disclaimer

I am not a cryptographer. Use at your own risk.

License

Copyright 2018, Mark George

FreeBSD License (BSD-2-Clause)

https://opensource.org/licenses/BSD-2-Clause