public final class PasswordUtils extends Object
This class uses the
PBKDF2WithHmacSHA512 algorithm for
generating 512-bit cryptographic keys. This is a
Password-Based-Key-Derivative Function (PBKDF) which is set to mix the hash
at least 216 (65536) times. Salt for this hashing algorithm is
generate using a SecureRandom
, which is a cryptographically-secure
random number generator.
A blog post, inspired by writing this class, can be found on my Dev.To page. It contains a thorough explanation of this code, while the text below only provides example usage.
To generate a salt
string, do:
jshell> import watson.*
jshell> String salt = PasswordUtils.generateSalt(512).get()
salt ==> "1T1uB6kjrp9YEBTvROPa8n8VbOGE+WJk4ds5asPxzH76HUEu ... 18Ly52X02aAfgUhKHo4B9JXk="
Then, hash the password and generate the key:
jshell> String key = PasswordUtils.hashPassword("Of Salesmen!", salt).get()
key ==> "AszLKBIMpxGdUKlcGryNUizi7yKhVGOqpyrxpT6UOU+XG6ie ... rZGgLP7wq/HhBmKPdqXG8eA=="
(Try not to store the password as a String
anywhere, if you can
help it.) Then, you can tell if a user-entered password is correct:
jshell> PasswordUtils.verifyPassword("Of Salesmen!", key, salt)
$4 ==> true
jshell> PasswordUtils.verifyPassword("By-Tor! And the Snow Dog!", key, salt)
$5 ==> false
Modifier and Type | Method | Description |
---|---|---|
static Optional<String> |
generateSalt(int length) |
Generates a random
byte[] of the given length using
SecureRandom.getInstanceStrong() and returns that array as a
base-64-encoded String , wrapped in an Optional . |
static Optional<String> |
hashPassword(String password,
String salt) |
Hashes the given password using the
PBKDF2WithHmacSHA512 algorithm,
mixing at least 216 times, generating a 512-bit key,
which is returned as a base-64-encoded
String . |
static boolean |
verifyPassword(String password,
String key,
String salt) |
Given the
password and the salt used to hash that
password, verifies that the cryptographic key generated matches the given
key . |
public static Optional<String> generateSalt(int length)
byte[]
of the given length
using
SecureRandom.getInstanceStrong()
and returns that array as a
base-64-encoded String
, wrapped in an Optional
.
Returns an empty Optional
if length
is < 1
. A length
of at least 32 is recommended, though the
default in this package is 512.
length
- length of the random byte[]
to generateString
to use as the second argument to
hashPassword()
, wrapped in an
Optional
public static Optional<String> hashPassword(String password, String salt)
String
.
Returns an empty Optional
if the algorithm
"PBKDF2WithHmacSHA512" can't be found in this Java distribution or if the
PBEKey otherwise cannot be created.
password
- password to hashsalt
- extra random string to use in the hash mixing algorithmOptional<String>
, or
an empty Optional
if there was a problempublic static boolean verifyPassword(String password, String key, String salt)
password
and the salt
used to hash that
password, verifies that the cryptographic key generated matches the given
key
.
Returns false
if the password
and salt
do not
generate the key
, or if hashPassword(java.lang.String,java.lang.String)
with password
and salt
as arguments returns
an empty Optional
.
password
- password to verifykey
- cryptographic key assumed to have been generated from the given
password
salt
- salt used to generate key
(along with original password)true
if the password
and salt
can be used
to reconstruct the key
, i.e. if the password
is correctCopyright © 2018–2019 IBAT. All rights reserved.