Skip to content

Commit

Permalink
Fix not returning correct hash version when verifying
Browse files Browse the repository at this point in the history
[Breaking API Change]

refs #24
  • Loading branch information
patrickfav committed Oct 20, 2019
1 parent 5cd1dfd commit c2f0f26
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 29 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG
Expand Up @@ -2,6 +2,11 @@

## v0.9.0
* fix license headers and correct credits to jBcrypt
* fix not returning correct hash version when verifying #24

### Breaking Changes

* `verify(byte[] password, int cost, byte[] salt, byte[] rawBcryptHash23Bytes)` signature changed, added `version` property (see #24)

## v0.8.0

Expand Down
Expand Up @@ -503,7 +503,7 @@ private Result verify(byte[] password, byte[] bcryptHash, Version requiredVersio
return new Result(hashData, false);
}

return verify(password, hashData.cost, hashData.rawSalt, hashData.rawHash);
return verify(password, hashData.cost, hashData.rawSalt, hashData.rawHash, hashData.version);
} catch (IllegalBCryptFormatException e) {
return new Result(e);
}
Expand All @@ -524,7 +524,7 @@ private Result verify(byte[] password, byte[] bcryptHash, Version requiredVersio
* @return result object, see {@link Result} for more info
*/
public Result verify(byte[] password, HashData bcryptHashData) {
return verify(password, bcryptHashData.cost, bcryptHashData.rawSalt, bcryptHashData.rawHash);
return verify(password, bcryptHashData.cost, bcryptHashData.rawSalt, bcryptHashData.rawHash, bcryptHashData.version);
}

/**
Expand All @@ -541,14 +541,15 @@ public Result verify(byte[] password, HashData bcryptHashData) {
* @param cost cost (log2 factor) which was used to create the hash
* @param salt 16 byte raw hash value (not radix64 version) which was used to create the hash
* @param rawBcryptHash23Bytes 23 byte raw bcrypt hash value (not radix64 version)
* @param version the version of the provided hash
* @return result object, see {@link Result} for more info
*/
public Result verify(byte[] password, int cost, byte[] salt, byte[] rawBcryptHash23Bytes) {
public Result verify(byte[] password, int cost, byte[] salt, byte[] rawBcryptHash23Bytes, Version version) {
Objects.requireNonNull(password);
Objects.requireNonNull(rawBcryptHash23Bytes);
Objects.requireNonNull(salt);

HashData hashData = BCrypt.withDefaults().hashRaw(cost, salt, password);
HashData hashData = BCrypt.with(version).hashRaw(cost, salt, password);
return new Result(hashData, Bytes.wrap(hashData.rawHash).equalsConstantTime(rawBcryptHash23Bytes));
}
}
Expand Down
Expand Up @@ -263,23 +263,17 @@ public void verifyWithResult() {
byte[] hash = bCrypt.hash(8, Bytes.random(16).array(), pw);

BCrypt.Result result = BCrypt.verifyer().verify(pw, hash);
assertTrue(result.verified);
assertTrue(result.validFormat);
assertEquals(BCrypt.Version.VERSION_2A, result.details.version);
assertEquals(8, result.details.cost);
assertResult(result, true, BCrypt.Version.VERSION_2A, 8);
}

@Test
public void verifyRawByteArrays() {
BCrypt.Hasher bCrypt = BCrypt.withDefaults();
byte[] pw = Bytes.random(24).encodeBase36().getBytes();
byte[] pw = Bytes.random(24).encodeRadix(36).getBytes();
BCrypt.HashData hash = bCrypt.hashRaw(6, Bytes.random(16).array(), pw);

BCrypt.Result result = BCrypt.verifyer().verify(pw, hash);
assertTrue(result.verified);
assertTrue(result.validFormat);
assertEquals(BCrypt.Version.VERSION_2A, result.details.version);
assertEquals(6, result.details.cost);
assertResult(result, true, BCrypt.Version.VERSION_2A, 6);
}

@Test
Expand All @@ -288,11 +282,8 @@ public void verifyRawByteArrays2() {
byte[] pw = Bytes.random(24).encodeBase36().getBytes();
BCrypt.HashData hash = bCrypt.hashRaw(7, Bytes.random(16).array(), pw);

BCrypt.Result result = BCrypt.verifyer().verify(pw, hash.cost, hash.rawSalt, hash.rawHash);
assertTrue(result.verified);
assertTrue(result.validFormat);
assertEquals(BCrypt.Version.VERSION_2A, result.details.version);
assertEquals(7, result.details.cost);
BCrypt.Result result = BCrypt.verifyer().verify(pw, hash.cost, hash.rawSalt, hash.rawHash, hash.version);
assertResult(result, true, BCrypt.Version.VERSION_2A, 7);
}

@Test
Expand All @@ -302,10 +293,7 @@ public void verifyWithResultChars() {
char[] hash = bCrypt.hashToChar(6, pw.toCharArray());

BCrypt.Result result = BCrypt.verifyer().verify(pw.toCharArray(), hash);
assertTrue(result.verified);
assertTrue(result.validFormat);
assertEquals(BCrypt.Version.VERSION_2A, result.details.version);
assertEquals(6, result.details.cost);
assertResult(result, true, BCrypt.Version.VERSION_2A, 6);
}

@Test
Expand All @@ -315,10 +303,7 @@ public void verifyIncorrectStrictVersion() {
byte[] hash = bCrypt.hash(5, Bytes.random(16).array(), pw);

BCrypt.Result result = BCrypt.verifyer().verifyStrict(pw, hash, BCrypt.Version.VERSION_2A);
assertFalse(result.verified);
assertTrue(result.validFormat);
assertEquals(BCrypt.Version.VERSION_2Y, result.details.version);
assertEquals(5, result.details.cost);
assertResult(result, false, BCrypt.Version.VERSION_2Y, 5);
}

@Test
Expand All @@ -328,10 +313,28 @@ public void verifyIncorrectStrictVersionChars() {
char[] hash = bCrypt.hashToChar(5, pw.toCharArray());

BCrypt.Result result = BCrypt.verifyer().verifyStrict(pw.toCharArray(), hash, BCrypt.Version.VERSION_2A);
assertFalse(result.verified);
assertResult(result, false, BCrypt.Version.VERSION_2X, 5);
}

@Test
public void verifyCorrectNonDefaultVersion() {
BCrypt.Version version = BCrypt.Version.VERSION_2X;
int cost = 4;
BCrypt.Hasher bCrypt = BCrypt.with(version);
String pw = "8PAsdjhlkjhkjla_ääas#d";
BCrypt.HashData hash1 = bCrypt.hashRaw(cost, Bytes.random(16).array(), Bytes.from(pw).array());
char[] hash2 = bCrypt.hashToChar(cost, pw.toCharArray());

assertResult(BCrypt.verifyer().verify(pw.toCharArray(), hash2), true, version, cost);
assertResult(BCrypt.verifyer().verifyStrict(pw.toCharArray(), hash2, version), true, version, cost);
assertResult(BCrypt.verifyer().verify(Bytes.from(pw).array(), hash1), true, version, cost);
}

private void assertResult(BCrypt.Result result, boolean verified, BCrypt.Version version, int cost) {
assertEquals(verified, result.verified);
assertTrue(result.validFormat);
assertEquals(BCrypt.Version.VERSION_2X, result.details.version);
assertEquals(5, result.details.cost);
assertEquals(version, result.details.version);
assertEquals(cost, result.details.cost);
}

@Test
Expand Down

0 comments on commit c2f0f26

Please sign in to comment.