use of org.wildfly.security.password.interfaces.BCryptPassword in project quarkus by quarkusio.
the class BcryptUtil method bcryptHash.
/**
* Produces a Modular Crypt Format bcrypt hash of the given password, using the specified salt and the specified iteration
* count.
*
* @param password the password to hash
* @param iterationCount the number of iterations to use while hashing
* @param salt the salt to use while hashing
* @return the Modular Crypt Format bcrypt hash of the given password
* @throws NullPointerException if the password or salt are null
* @throws IllegalArgumentException if the iterationCount parameter is negative or zero, or if the salt length is not equal
* to 16
*/
public static String bcryptHash(String password, int iterationCount, byte[] salt) {
if (iterationCount <= 0) {
throw new IllegalArgumentException("Iteration count must be greater than zero");
}
Objects.requireNonNull(password, "password is required");
Objects.requireNonNull(salt, "salt is required");
if (salt.length != BCryptPassword.BCRYPT_SALT_SIZE) {
throw new IllegalArgumentException("Salt length must be exactly " + BCryptPassword.BCRYPT_SALT_SIZE + " bytes");
}
PasswordFactory passwordFactory;
try {
passwordFactory = PasswordFactory.getInstance(BCryptPassword.ALGORITHM_BCRYPT, provider);
} catch (NoSuchAlgorithmException e) {
// can't really happen
throw new RuntimeException(e);
}
IteratedSaltedPasswordAlgorithmSpec iteratedAlgorithmSpec = new IteratedSaltedPasswordAlgorithmSpec(iterationCount, salt);
EncryptablePasswordSpec encryptableSpec = new EncryptablePasswordSpec(password.toCharArray(), iteratedAlgorithmSpec);
try {
BCryptPassword original = (BCryptPassword) passwordFactory.generatePassword(encryptableSpec);
return ModularCrypt.encodeAsString(original);
} catch (InvalidKeySpecException e) {
// can't really happen
throw new RuntimeException(e);
}
}
use of org.wildfly.security.password.interfaces.BCryptPassword in project wildfly-elytron by wildfly-security.
the class BCryptPasswordTest method testGetKeySpecFromString.
@Test
public void testGetKeySpecFromString() throws Exception {
String cryptString = "$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG";
// get the spec by parsing the crypt string.
PasswordFactory factory = PasswordFactory.getInstance(ALGORITHM_BCRYPT);
BCryptPassword password = (BCryptPassword) factory.translate(ModularCrypt.decode(cryptString));
Assert.assertEquals(12, password.getIterationCount());
Assert.assertEquals(BCryptPassword.BCRYPT_SALT_SIZE, password.getSalt().length);
// use the spec to build a new crypt string and compare it to the original one.
Assert.assertEquals(cryptString, ModularCrypt.encodeAsString(password));
}
use of org.wildfly.security.password.interfaces.BCryptPassword in project wildfly-elytron by wildfly-security.
the class BCryptPasswordTest method testHashAgainstPassLib.
/**
* <p>
* For this test the crypt string was generated using the Python PassLib bcrypt implementation.
* </p>
*
* @throws Exception if an error occurs while running the test.
*/
@Test
public void testHashAgainstPassLib() throws Exception {
String cryptString = "$2a$12$NT0I31Sa7ihGEWpka9ASYeEFkhuTNeBQ2xfZskIiiJeyFXhRgS.Sy";
char[] correctPassword = "password".toCharArray();
PasswordFactory factory = PasswordFactory.getInstance(ALGORITHM_BCRYPT);
BCryptPassword password = (BCryptPassword) factory.translate(ModularCrypt.decode(cryptString));
// use the obtained spec to build a BCryptPasswordImpl, then verify the hash using the correct password.
Assert.assertTrue(factory.verify(password, correctPassword));
// check if an incorrect password gets rejected.
Assert.assertFalse(factory.verify(password, "wrongpassword".toCharArray()));
// now use the EncryptablePasswordSpec to build a new password and check if the hashed bytes matches those that
// were parsed and stored in the spec.
password = (BCryptPassword) factory.generatePassword(new EncryptablePasswordSpec(correctPassword, new IteratedSaltedPasswordAlgorithmSpec(password.getIterationCount(), password.getSalt())));
Assert.assertArrayEquals(password.getHash(), password.getHash());
// use the new password to obtain a spec and then check if the spec yields the same crypt string.
Assert.assertEquals(cryptString, ModularCrypt.encodeAsString(password));
}
use of org.wildfly.security.password.interfaces.BCryptPassword in project wildfly-elytron by wildfly-security.
the class PasswordSupportTest method testVerifyAndObtainBCryptPasswordCredential.
@Test
public void testVerifyAndObtainBCryptPasswordCredential() throws Exception {
String userName = "john";
String userPassword = "bcrypt_abcd1234";
byte[] salt = generateRandomSalt(BCRYPT_SALT_SIZE);
int iterationCount = 10;
createBcryptPasswordTable(userName, userPassword, salt, iterationCount);
PasswordKeyMapper passwordKeyMapper = PasswordKeyMapper.builder().setDefaultAlgorithm(BCryptPassword.ALGORITHM_BCRYPT).setHashColumn(1).setSaltColumn(2).setIterationCountColumn(3).build();
JdbcSecurityRealm securityRealm = JdbcSecurityRealm.builder().principalQuery("SELECT password, salt, iterationCount FROM user_bcrypt_password where name = ?").withMapper(passwordKeyMapper).from(dataSourceRule.getDataSource()).setProviders(ELYTRON_PASSWORD_PROVIDERS).build();
assertEquals(SupportLevel.POSSIBLY_SUPPORTED, securityRealm.getCredentialAcquireSupport(PasswordCredential.class, BCryptPassword.ALGORITHM_BCRYPT, null));
RealmIdentity realmIdentity = securityRealm.getRealmIdentity(new NamePrincipal(userName));
assertEquals(SupportLevel.SUPPORTED, realmIdentity.getCredentialAcquireSupport(PasswordCredential.class, BCryptPassword.ALGORITHM_BCRYPT, null));
assertTrue(realmIdentity.verifyEvidence(new PasswordGuessEvidence(userPassword.toCharArray())));
assertFalse(realmIdentity.verifyEvidence(new PasswordGuessEvidence("invalid".toCharArray())));
BCryptPassword storedPassword = realmIdentity.getCredential(PasswordCredential.class, BCryptPassword.ALGORITHM_BCRYPT).getPassword(BCryptPassword.class);
assertNotNull(storedPassword);
}
use of org.wildfly.security.password.interfaces.BCryptPassword in project wildfly-elytron by wildfly-security.
the class ModularCrypt method getCryptStringToBuilder.
private static StringBuilder getCryptStringToBuilder(Password password) throws InvalidKeySpecException {
Assert.checkNotNullParam("password", password);
final StringBuilder b = new StringBuilder();
if (password instanceof BCryptPassword) {
BCryptPassword spec = (BCryptPassword) password;
b.append("$2a$");
if (spec.getIterationCount() < 10)
b.append(0);
b.append(spec.getIterationCount());
b.append("$");
ByteIterator.ofBytes(spec.getSalt()).base64Encode(BCRYPT, false).drainTo(b);
ByteIterator.ofBytes(spec.getHash()).base64Encode(BCRYPT, false).drainTo(b);
} else if (password instanceof BSDUnixDESCryptPassword) {
b.append('_');
final BSDUnixDESCryptPassword spec = (BSDUnixDESCryptPassword) password;
final int iterationCount = spec.getIterationCount();
b.appendCodePoint(MOD_CRYPT.encode(iterationCount & 0x3f));
b.appendCodePoint(MOD_CRYPT.encode((iterationCount >> 6) & 0x3f));
b.appendCodePoint(MOD_CRYPT.encode((iterationCount >> 12) & 0x3f));
b.appendCodePoint(MOD_CRYPT.encode((iterationCount >> 18) & 0x3f));
final int salt = spec.getSalt();
b.appendCodePoint(MOD_CRYPT.encode(salt & 0x3f));
b.appendCodePoint(MOD_CRYPT.encode((salt >> 6) & 0x3f));
b.appendCodePoint(MOD_CRYPT.encode((salt >> 12) & 0x3f));
b.appendCodePoint(MOD_CRYPT.encode((salt >> 18) & 0x3f));
ByteIterator.ofBytes(spec.getHash()).base64Encode(MOD_CRYPT, false).drainTo(b);
} else if (password instanceof UnixDESCryptPassword) {
final UnixDESCryptPassword spec = (UnixDESCryptPassword) password;
final short salt = spec.getSalt();
b.appendCodePoint(MOD_CRYPT.encode(salt & 0x3f));
b.appendCodePoint(MOD_CRYPT.encode((salt >> 6) & 0x3f));
ByteIterator.ofBytes(spec.getHash()).base64Encode(MOD_CRYPT, false).drainTo(b);
} else if (password instanceof UnixMD5CryptPassword) {
b.append("$1$");
final UnixMD5CryptPassword spec = (UnixMD5CryptPassword) password;
final byte[] salt = spec.getSalt();
for (final byte sb : salt) {
b.append((char) (sb & 0xff));
}
b.append('$');
ByteIterator.ofBytes(spec.getHash(), MD5_IDX).base64Encode(MOD_CRYPT_LE, false).drainTo(b);
} else if (password instanceof SunUnixMD5CryptPassword) {
final SunUnixMD5CryptPassword spec = (SunUnixMD5CryptPassword) password;
final int iterationCount = spec.getIterationCount();
if (iterationCount > 0) {
b.append("$md5,rounds=").append(iterationCount).append('$');
} else {
b.append("$md5$");
}
final byte[] salt = spec.getSalt();
for (final byte sb : salt) {
b.append((char) (sb & 0xff));
}
switch(spec.getAlgorithm()) {
case ALGORITHM_SUN_CRYPT_MD5:
{
b.append("$$");
break;
}
case ALGORITHM_SUN_CRYPT_MD5_BARE_SALT:
{
b.append("$");
break;
}
default:
{
throw log.invalidKeySpecUnrecognizedKeySpecAlgorithm();
}
}
ByteIterator.ofBytes(spec.getHash(), MD5_IDX).base64Encode(MOD_CRYPT_LE, false).drainTo(b);
} else if (password instanceof UnixSHACryptPassword) {
final UnixSHACryptPassword spec = (UnixSHACryptPassword) password;
final int[] interleave;
switch(spec.getAlgorithm()) {
case ALGORITHM_CRYPT_SHA_256:
{
b.append("$5$");
interleave = SHA_256_IDX;
break;
}
case ALGORITHM_CRYPT_SHA_512:
{
b.append("$6$");
interleave = SHA_512_IDX;
break;
}
default:
{
throw log.invalidKeySpecUnrecognizedKeySpecAlgorithm();
}
}
final int iterationCount = spec.getIterationCount();
if (iterationCount != 5_000) {
b.append("rounds=").append(iterationCount).append('$');
}
final byte[] salt = spec.getSalt();
for (final byte sb : salt) {
b.append((char) (sb & 0xff));
}
b.append('$');
ByteIterator.ofBytes(spec.getHash(), interleave).base64Encode(MOD_CRYPT_LE, false).drainTo(b);
} else if (password instanceof MaskedPassword) {
final MaskedPassword spec = (MaskedPassword) password;
b.append('$').append(spec.getAlgorithm()).append('$');
b.append(spec.getInitialKeyMaterial()).append('$');
b.append(spec.getIterationCount()).append('$');
ByteIterator.ofBytes(spec.getSalt()).base64Encode().drainTo(b).append('$');
ByteIterator.ofBytes(spec.getMaskedPasswordBytes()).base64Encode().drainTo(b);
if (spec.getInitializationVector() != null) {
b.append('$');
ByteIterator.ofBytes(spec.getInitializationVector()).base64Encode().drainTo(b);
}
} else {
throw log.invalidKeySpecPasswordSpecCannotBeRenderedAsString();
}
return b;
}
Aggregations