Newer
Older
BouncyScrypt / 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:

```
$919553$mshp5K/vaKkdSzbRqqMTLwr76eSurBsTuVCIIDxuZEE6u093MHBk0Miaq3Qp/Vd7QdP/WeOglVg6W/omiNfC8g==$eV7FfnHnmwyCU8i4rAHQ6NO5RZp53/V1Wr3jsFCc1BqM6yvmGp6BfG7VFrmz21cFlzf4F/aPkgRuO5DRBHgIPQ==$
```

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

The standard scrypt work factors are used:

* N = 32768
* 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:

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

Checking a password against a hash:

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

## Paranoid mode (using char[] and CharBuffer objects)

Generating a hash:

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

Checking a hash against a password:

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

Overwriting the sensitive data once you have finished with it:

```java
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