Skip to content

Commit

Permalink
Allow for custom max password length in 'Version' (#28)
Browse files Browse the repository at this point in the history
Allow for custom max password length in 'Version'
  • Loading branch information
patrickfav authored Oct 29, 2019
2 parents 2b6befe + e8e0706 commit 009cbd8
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 95 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
* fix license headers and correct credits to jBcrypt
* add long-password strategy to verifier #21
* fix not returning correct hash version when verifying #24
* allow for custom max password length in Version #22

### Breaking Changes

* `verify(byte[] password, int cost, byte[] salt, byte[] rawBcryptHash23Bytes)` signature changed, added `version` property (see #24)
* `LongPasswordStrategies` factory methods now require the version for the max password length (see #22)
* Verifier now accepts `Version` as a constructor parameter and `verifyStrict` therefore does not need one (see #22)

## v0.8.0

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ usually you should prefer `char[]` or `byte[]` APIs.
If you want the hash verification to only verify for a specific version you can use `verifyStrict()`

```java
byte[] hash2y = BCrypt.with(BCrypt.Version.VERSION_2Y).hash(6, password.getBytes(StandardCharsets.UTF_8));
BCrypt.Result resultStrict = BCrypt.verifyer().verifyStrict(password.getBytes(StandardCharsets.UTF_8), hash2y, BCrypt.Version.VERSION_2A);
byte[] hash2y = BCrypt.with(BCrypt.Version.VERSION_2Y).hash(6, password.getBytes(StandardCharsets.UTF_8));
BCrypt.Result resultStrict = BCrypt.verifyer(BCrypt.Version.VERSION_2A).verifyStrict(password.getBytes(StandardCharsets.UTF_8), hash2y);
// resultStrict.verified == false
```

Expand Down
194 changes: 140 additions & 54 deletions modules/bcrypt/src/main/java/at/favre/lib/crypto/bcrypt/BCrypt.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public BCrypt.HashData parse(byte[] bcryptHash) throws IllegalBCryptFormatExcept

int parsedCostFactor;
try {
parsedCostFactor = Integer.valueOf(new String(costBytes, defaultCharset));
parsedCostFactor = Integer.parseInt(new String(costBytes, defaultCharset));
} catch (NumberFormatException e) {
throw new IllegalBCryptFormatException("cannot parse cost factor '" + new String(costBytes, defaultCharset) + "'");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package at.favre.lib.crypto.bcrypt;

import java.util.Objects;

/**
* Factory for default {@link LongPasswordStrategy} implementatins
*/
Expand All @@ -11,28 +13,31 @@ private LongPasswordStrategies() {
/**
* See {@link at.favre.lib.crypto.bcrypt.LongPasswordStrategy.TruncateStrategy}
*
* @param version required to get the max allowed pw length
* @return new instance
*/
public static LongPasswordStrategy truncate() {
return new LongPasswordStrategy.TruncateStrategy(BCrypt.MAX_PW_LENGTH_BYTE);
public static LongPasswordStrategy truncate(BCrypt.Version version) {
return new LongPasswordStrategy.TruncateStrategy(Objects.requireNonNull(version).allowedMaxPwLength);
}

/**
* See {@link at.favre.lib.crypto.bcrypt.LongPasswordStrategy.Sha512DerivationStrategy}
*
* @param version required to get the max allowed pw length
* @return new instance
*/
public static LongPasswordStrategy hashSha512() {
return new LongPasswordStrategy.Sha512DerivationStrategy(BCrypt.MAX_PW_LENGTH_BYTE);
public static LongPasswordStrategy hashSha512(BCrypt.Version version) {
return new LongPasswordStrategy.Sha512DerivationStrategy(Objects.requireNonNull(version).allowedMaxPwLength);
}

/**
* See {@link at.favre.lib.crypto.bcrypt.LongPasswordStrategy.StrictMaxPasswordLengthStrategy}
*
* @param version required to get the max allowed pw length
* @return new instance
*/
public static LongPasswordStrategy strict() {
return new LongPasswordStrategy.StrictMaxPasswordLengthStrategy(BCrypt.MAX_PW_LENGTH_BYTE);
public static LongPasswordStrategy strict(BCrypt.Version version) {
return new LongPasswordStrategy.StrictMaxPasswordLengthStrategy(Objects.requireNonNull(version).allowedMaxPwLength);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
public class BcryptTest {
@Rule
public RepeatRule repeatRule = new RepeatRule();
public static final Charset UTF_8 = StandardCharsets.UTF_8;
static final Charset UTF_8 = StandardCharsets.UTF_8;
private static final BCrypt.Version DEFAULT_VERSION = BCrypt.Version.VERSION_2A;

private BcryptTestEntry[] testEntries = new BcryptTestEntry[]{
// see: https://stackoverflow.com/a/12761326/774398
Expand Down Expand Up @@ -85,10 +86,10 @@ public void readmeExamples() {
BCrypt.Result result = BCrypt.verifyer().verify(password.getBytes(StandardCharsets.UTF_8), bcryptHashBytes);
//verify strict
byte[] hash2y = BCrypt.with(BCrypt.Version.VERSION_2Y).hash(6, password.getBytes(StandardCharsets.UTF_8));
BCrypt.Result resultStrict = BCrypt.verifyer().verifyStrict(password.getBytes(StandardCharsets.UTF_8), hash2y, BCrypt.Version.VERSION_2A);
BCrypt.Result resultStrict = BCrypt.verifyer(BCrypt.Version.VERSION_2A).verifyStrict(password.getBytes(StandardCharsets.UTF_8), hash2y);
//overlong passwords
BCrypt.with(LongPasswordStrategies.truncate()).hash(6, new byte[100]);
BCrypt.with(LongPasswordStrategies.hashSha512()).hash(6, new byte[100]);
BCrypt.with(LongPasswordStrategies.truncate(BCrypt.Version.VERSION_2Y)).hash(6, new byte[100]);
BCrypt.with(LongPasswordStrategies.hashSha512(BCrypt.Version.VERSION_2Y)).hash(6, new byte[100]);
//custom salt and secure random
BCrypt.withDefaults().hash(6, Bytes.random(16).array(), password.getBytes(StandardCharsets.UTF_8));
BCrypt.with(new SecureRandom()).hash(6, password.getBytes(StandardCharsets.UTF_8));
Expand Down Expand Up @@ -119,12 +120,12 @@ public void testSecureRandom() throws Exception {

@Test
public void testLongPasswordStrategy() throws Exception {
checkHash(BCrypt.with(new LongPasswordStrategy.TruncateStrategy(BCrypt.MAX_PW_LENGTH_BYTE)));
checkHash(BCrypt.with(new LongPasswordStrategy.TruncateStrategy(DEFAULT_VERSION.allowedMaxPwLength)));
}

@Test
public void testFullyCustom() throws Exception {
checkHash(BCrypt.with(BCrypt.Version.VERSION_2Y, new SecureRandom(), new LongPasswordStrategy.TruncateStrategy(BCrypt.MAX_PW_LENGTH_BYTE)));
checkHash(BCrypt.with(BCrypt.Version.VERSION_2Y, new LongPasswordStrategy.TruncateStrategy(BCrypt.Version.VERSION_2Y.allowedMaxPwLength)));
}

private void checkHash(BCrypt.Hasher bCrypt) throws Exception {
Expand Down Expand Up @@ -206,28 +207,28 @@ public void createHashWithCharPwNull() {

@Test(expected = IllegalArgumentException.class)
public void createHashWithPwTooLong() {
BCrypt.withDefaults().hash(6, new byte[16], new byte[BCrypt.MAX_PW_LENGTH_BYTE + 1]);
BCrypt.withDefaults().hash(6, new byte[16], new byte[DEFAULT_VERSION.allowedMaxPwLength + 1]);
}

@Test(expected = IllegalArgumentException.class)
public void createHashWithPwTooLong2() {
BCrypt.withDefaults().hash(6, new byte[16], new byte[BCrypt.MAX_PW_LENGTH_BYTE + 2]);
BCrypt.withDefaults().hash(6, new byte[16], new byte[DEFAULT_VERSION.allowedMaxPwLength + 2]);
}

@Test
public void testLongPassword() {
byte[] pw = Bytes.random(BCrypt.MAX_PW_LENGTH_BYTE).array();
byte[] pw = Bytes.random(DEFAULT_VERSION.allowedMaxPwLength).array();
byte[] bcryptHashBytes = BCrypt.withDefaults().hash(4, pw);
assertTrue(BCrypt.verifyer().verify(pw, bcryptHashBytes).verified);
}

@Test
public void testLongTruncatedPassword() {
byte[] pw = Bytes.random(BCrypt.MAX_PW_LENGTH_BYTE + 2).array();
byte[] pw = Bytes.random(DEFAULT_VERSION.allowedMaxPwLength + 2).array();
byte[] salt = Bytes.random(16).array();
byte[] bcryptHashBytes1a = BCrypt.with(LongPasswordStrategies.truncate()).hash(4, salt, pw);
byte[] bcryptHashBytes1b = BCrypt.with(LongPasswordStrategies.truncate()).hash(4, salt, Bytes.wrap(pw).resize(BCrypt.MAX_PW_LENGTH_BYTE + 1, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
byte[] bcryptHashBytes2 = BCrypt.withDefaults().hash(4, salt, Bytes.wrap(pw).resize(BCrypt.MAX_PW_LENGTH_BYTE, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
byte[] bcryptHashBytes1a = BCrypt.with(LongPasswordStrategies.truncate(DEFAULT_VERSION)).hash(4, salt, pw);
byte[] bcryptHashBytes1b = BCrypt.with(LongPasswordStrategies.truncate(DEFAULT_VERSION)).hash(4, salt, Bytes.wrap(pw).resize(DEFAULT_VERSION.allowedMaxPwLength + 1, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
byte[] bcryptHashBytes2 = BCrypt.withDefaults().hash(4, salt, Bytes.wrap(pw).resize(DEFAULT_VERSION.allowedMaxPwLength, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());

assertArrayEquals(bcryptHashBytes1a, bcryptHashBytes1b);
assertArrayEquals(bcryptHashBytes1a, bcryptHashBytes2);
Expand All @@ -240,7 +241,7 @@ public void testVariousPwLengthShouldBeDifferentHashes() {

Set<String> hashes = new HashSet<>();
for (int i = 0; i < 72; i++) {
BCrypt.HashData data = BCrypt.with(LongPasswordStrategies.truncate()).hashRaw(4, salt, pw.resize(i, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
BCrypt.HashData data = BCrypt.with(LongPasswordStrategies.truncate(DEFAULT_VERSION)).hashRaw(4, salt, pw.resize(i, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
String hashHexString = Bytes.wrap(data.rawHash).encodeHex();
assertFalse("hash already in set for length " + i, hashes.contains(hashHexString));
hashes.add(hashHexString);
Expand All @@ -249,10 +250,10 @@ public void testVariousPwLengthShouldBeDifferentHashes() {

@Test
public void testLongHashedPassword() {
byte[] pw = Bytes.random(BCrypt.MAX_PW_LENGTH_BYTE + 2).array();
byte[] pw = Bytes.random(DEFAULT_VERSION.allowedMaxPwLength + 2).array();
byte[] salt = Bytes.random(16).array();
byte[] bcryptHashBytes1 = BCrypt.with(LongPasswordStrategies.hashSha512()).hash(4, salt, pw);
byte[] bcryptHashBytes2 = BCrypt.with(LongPasswordStrategies.hashSha512()).hash(4, salt, Bytes.wrap(pw).resize(BCrypt.MAX_PW_LENGTH_BYTE + 1, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
byte[] bcryptHashBytes1 = BCrypt.with(LongPasswordStrategies.hashSha512(DEFAULT_VERSION)).hash(4, salt, pw);
byte[] bcryptHashBytes2 = BCrypt.with(LongPasswordStrategies.hashSha512(DEFAULT_VERSION)).hash(4, salt, Bytes.wrap(pw).resize(DEFAULT_VERSION.allowedMaxPwLength + 1, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
assertFalse(Bytes.wrap(bcryptHashBytes1).equals(bcryptHashBytes2));
}

Expand Down Expand Up @@ -282,7 +283,7 @@ 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, hash.version);
BCrypt.Result result = BCrypt.verifyer().verify(pw, hash.cost, hash.rawSalt, hash.rawHash);
assertResult(result, true, BCrypt.Version.VERSION_2A, 7);
}

Expand All @@ -302,7 +303,7 @@ public void verifyIncorrectStrictVersion() {
byte[] pw = "78PHasdhklöALÖö".getBytes();
byte[] hash = bCrypt.hash(5, Bytes.random(16).array(), pw);

BCrypt.Result result = BCrypt.verifyer().verifyStrict(pw, hash, BCrypt.Version.VERSION_2A);
BCrypt.Result result = BCrypt.verifyer(BCrypt.Version.VERSION_2A).verifyStrict(pw, hash);
assertResult(result, false, BCrypt.Version.VERSION_2Y, 5);
}

Expand All @@ -312,7 +313,7 @@ public void verifyIncorrectStrictVersionChars() {
String pw = "8PAsdjhlkjhkjla_ääas#d";
char[] hash = bCrypt.hashToChar(5, pw.toCharArray());

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

Expand All @@ -325,9 +326,9 @@ public void verifyCorrectNonDefaultVersion() {
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);
assertResult(BCrypt.verifyer(version).verify(pw.toCharArray(), hash2), true, version, cost);
assertResult(BCrypt.verifyer(version).verifyStrict(pw.toCharArray(), hash2), true, version, cost);
assertResult(BCrypt.verifyer(version).verify(Bytes.from(pw).array(), hash1), true, version, cost);
}

private void assertResult(BCrypt.Result result, boolean verified, BCrypt.Version version, int cost) {
Expand Down Expand Up @@ -400,14 +401,15 @@ public void testHashDataWipe() {
@Test
public void testVersionPojoMethods() {
assertEquals(BCrypt.Version.VERSION_2A, BCrypt.Version.VERSION_2A);
assertEquals(BCrypt.Version.VERSION_2A, new BCrypt.Version(new byte[]{MAJOR_VERSION, 0x61}, true, true, null, null));
assertEquals(BCrypt.Version.VERSION_2Y, new BCrypt.Version(new byte[]{MAJOR_VERSION, 0x79}, true, true, null, null));
assertEquals(BCrypt.Version.VERSION_2A, new BCrypt.Version(new byte[]{MAJOR_VERSION, 0x61}, true, true, BCrypt.Version.DEFAULT_MAX_PW_LENGTH_BYTE, null, null));
assertEquals(BCrypt.Version.VERSION_2Y, new BCrypt.Version(new byte[]{MAJOR_VERSION, 0x79}, true, true, BCrypt.Version.DEFAULT_MAX_PW_LENGTH_BYTE, null, null));
assertEquals(BCrypt.Version.VERSION_2Y_NO_NULL_TERMINATOR, new BCrypt.Version(new byte[]{MAJOR_VERSION, 0x79}, true, false, BCrypt.Version.MAX_PW_LENGTH_BYTE, null, null));
assertNotEquals(BCrypt.Version.VERSION_2Y, BCrypt.Version.VERSION_2A);
assertNotEquals(BCrypt.Version.VERSION_2A, BCrypt.Version.VERSION_2B);
assertNotEquals(BCrypt.Version.VERSION_2X, BCrypt.Version.VERSION_2Y);

assertEquals(BCrypt.Version.VERSION_2A.hashCode(), BCrypt.Version.VERSION_2A.hashCode());
assertEquals(BCrypt.Version.VERSION_2A.hashCode(), new BCrypt.Version(new byte[]{MAJOR_VERSION, 0x61}, true, true, null, null).hashCode());
assertEquals(BCrypt.Version.VERSION_2A.hashCode(), new BCrypt.Version(new byte[]{MAJOR_VERSION, 0x61}, true, true, BCrypt.Version.DEFAULT_MAX_PW_LENGTH_BYTE, null, null).hashCode());

assertNotEquals(BCrypt.Version.VERSION_2Y.hashCode(), BCrypt.Version.VERSION_2A.hashCode());
assertNotEquals(BCrypt.Version.VERSION_2A.hashCode(), BCrypt.Version.VERSION_2B.hashCode());
Expand All @@ -416,12 +418,69 @@ public void testVersionPojoMethods() {

@Test
public void testVerifierWithLongPasswordStrategy() {
LongPasswordStrategy truncate = LongPasswordStrategies.truncate();
LongPasswordStrategy truncate = LongPasswordStrategies.truncate(BCrypt.Version.VERSION_2A);

byte[] pw = Bytes.random(200).array();
byte[] hash = BCrypt.with(truncate).hash(4, pw);

assertTrue(BCrypt.verifyer(truncate).verify(pw, hash).verified);
assertFalse(BCrypt.verifyer().verify(pw, hash).verified);
assertTrue(BCrypt.verifyer(BCrypt.Version.VERSION_2A, truncate).verify(pw, hash).verified);
assertFalse(BCrypt.verifyer(BCrypt.Version.VERSION_2A, LongPasswordStrategies.none()).verify(pw, hash).verified);
}

@Test
public void testWithNullTerminatorWithinPw_shouldNotTerminate() {
byte[] pw1 = Bytes.from("secret").append(0x00).append("butthereismore").array();
byte[] pw2 = Bytes.from("secret").array();

byte[] salt = Bytes.random(16).array();

String hash1 = Bytes.wrap(BCrypt.withDefaults().hash(4, salt, pw1)).toString();
String hash2 = Bytes.wrap(BCrypt.withDefaults().hash(4, salt, pw2)).toString();

assertNotEquals(hash1, hash2);
System.out.println(hash1 + "\n" + hash2);
}

@Test
public void testVersionWithNullTerminator() {
char[] pw = "myverlongpasswordthatisatleast72charslongandlongnothisisnotlongenoughyou".toCharArray();
assertEquals(72, pw.length);
assertEquals(72, Bytes.from(pw).length());

byte[] salt = Bytes.random(16).array();

byte[] hash1 = BCrypt.with(BCrypt.Version.VERSION_2Y_NO_NULL_TERMINATOR, LongPasswordStrategies.truncate(BCrypt.Version.VERSION_2Y_NO_NULL_TERMINATOR)).hash(4, salt, Bytes.from(pw).array());
byte[] hash2 = BCrypt.with(BCrypt.Version.VERSION_2Y, LongPasswordStrategies.truncate(BCrypt.Version.VERSION_2Y)).hash(4, salt, Bytes.from(pw).array());

assertNotEquals(Bytes.wrap(hash1).encodeUtf8(), Bytes.wrap(hash2).encodeUtf8());
System.out.println(Bytes.wrap(hash1).encodeUtf8() + "\n" + Bytes.wrap(hash2).encodeUtf8());
}

@Test
public void testReferenceValuesWithoutNullTerminator() {
char[] pw = "myverlongpasswordthatisatleast72charslongandlongnothisisnotlongenoughyou".toCharArray();

assertTrue(BCrypt.verifyer(BCrypt.Version.VERSION_2Y_NO_NULL_TERMINATOR).verify(pw, "$2y$04$d4CIUbwyucxm87BQnDWyI.xHDm2vyIZfBDOzjASNkn/yB.6lzLwOG".toCharArray()).verified);
assertTrue(BCrypt.verifyer(BCrypt.Version.VERSION_2Y_NO_NULL_TERMINATOR).verify(pw, "$2y$04$w8S7HTjIfG.8RRVOhLZWtuH6eei2l7NZ/VhYUrDJndAjDmOqK6E0W".toCharArray()).verified);
assertTrue(BCrypt.verifyer(BCrypt.Version.VERSION_2Y, LongPasswordStrategies.truncate(BCrypt.Version.VERSION_2Y)).verify(pw, "$2y$04$w8S7HTjIfG.8RRVOhLZWtu//55gj0VTX7XdNkQmDuPw.qQXsnvtkG".toCharArray()).verified);
}

@Test
public void verifyInferVersion() {
verifyInferedVersion("<.S.2K(Zq'", "$2y$04$VYAclAMpaXY/oqAo9yUpkuWmoYywaPzyhu56HxXpVltnBIfmO9tgu", BCrypt.Version.VERSION_2Y);
verifyInferedVersion("<.S.2K(Zq'", "$2x$04$VYAclAMpaXY/oqAo9yUpkuWmoYywaPzyhu56HxXpVltnBIfmO9tgu", BCrypt.Version.VERSION_2X);
verifyInferedVersion("<.S.2K(Zq'", "$2a$04$VYAclAMpaXY/oqAo9yUpkuWmoYywaPzyhu56HxXpVltnBIfmO9tgu", BCrypt.Version.VERSION_2A);
verifyInferedVersion("<.S.2K(Zq'", "$2b$04$VYAclAMpaXY/oqAo9yUpkuWmoYywaPzyhu56HxXpVltnBIfmO9tgu", BCrypt.Version.VERSION_2B);
}

private void verifyInferedVersion(String pw, String hash, BCrypt.Version expectedVersion) {
BCrypt.Result result = BCrypt.verifyer().verify(pw.toCharArray(), hash.toCharArray());
assertTrue(result.verified);
assertEquals(expectedVersion, result.details.version);
}

@Test(expected = IllegalArgumentException.class)
public void verifyStrictWithoutVersionShouldThrow() {
BCrypt.verifyer().verifyStrict("<.S.2K(Zq'".toCharArray(), "$2a$04$VYAclAMpaXY/oqAo9yUpkuWmoYywaPzyhu56HxXpVltnBIfmO9tgu".toCharArray());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@
public class LongPasswordStrategyTest {

private final int maxLength = 72;
private static final BCrypt.Version DEFAULT_VERSION = BCrypt.Version.VERSION_2A;

@Test
public void testFactory() {
assertNotNull(LongPasswordStrategies.hashSha512().derive(Bytes.random(100).array()));
assertNotNull(LongPasswordStrategies.truncate().derive(Bytes.random(100).array()));
assertNotNull(LongPasswordStrategies.hashSha512(DEFAULT_VERSION).derive(Bytes.random(100).array()));
assertNotNull(LongPasswordStrategies.truncate(DEFAULT_VERSION).derive(Bytes.random(100).array()));
assertNotNull(LongPasswordStrategies.none().derive(Bytes.random(100).array()));
}

@Test(expected = IllegalArgumentException.class)
public void testFactoryForStrictShouldThrowException() {
LongPasswordStrategies.strict().derive(Bytes.random(100).array());
LongPasswordStrategies.strict(DEFAULT_VERSION).derive(Bytes.random(100).array());
}

@Test
Expand Down

0 comments on commit 009cbd8

Please sign in to comment.