Lenny
I just checked: We implemented our own realm when our patch did not get
accepted. That has been a long time ago and I can't remember the
details.
So technically we are using BCrypt but are not affected when Shiro
changed anything about it.
Sorry for any confusion. I don't touch this stuff too often.
Best and cheers
Andreas
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
// Null username is invalid
if (username == null) {
throw new AccountException("Null usernames are not allowed by this
realm.");
}
Connection conn = null;
SimpleAuthenticationInfo info = null;
try {
conn = dataSource.getConnection();
String password = null;
String salt = null;
switch (saltStyle) {
case NO_SALT:
password = getPasswordForUser(conn, username)[0];
break;
case CRYPT:
/*
*
http://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-
* shadow-utils
*
* Example: $1$Etg2ExUZ$F9NTP7omafhKIlqaBMqng1
*
* The above shown encoded hash value can be further classified
into three
* different fields as below. 1. The first field is a numerical
number that
* tell's you the hashing algorithm that's being used.
*
* $1 = MD5 hashing algorithm. $2 =Blowfish Algorithm is in
use. $2a=eksblowfish
* Algorithm $5 =SHA-256 Algorithm $6 =SHA-512 Algorithm
*
* 2. The second field is the salt value Salt value is nothing
but a random data
* that's generated to combine with the original password,
inorder to increase
* the strength of the hash..
*
* 3.The last field is the hash value of salt+user password (we
will be
* discussing this shortly).
*
*/
String[] crypt = getPasswordForUser(conn,
username)[0].split("\\$");
CredentialsMatcher credentialsMatcher = getCredentialsMatcher();
if (credentialsMatcher instanceof HashedCredentialsMatcher) {
HashedCredentialsMatcher hashedCredentialsMatcher =
(HashedCredentialsMatcher) credentialsMatcher;
switch (crypt.length) {
// hash algorithm is not set
case 3:
// Hex decoding is ugly and should not be used
really
salt =
hashedCredentialsMatcher.isStoredCredentialsHexEncoded()
? new String(Hex.decode(crypt[1]))
: Base64.decodeToString(crypt[1]);
password = crypt[2];
break;
// hash algorithm is set
case 4:
String hashAlgorithm = crypt[1];
if (hashAlgorithm.equals("6"))
hashedCredentialsMatcher
.setHashAlgorithmName(Sha512Hash.ALGORITHM_NAME);
else if (hashAlgorithm.equals("5"))
hashedCredentialsMatcher
.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
else if (hashAlgorithm.equals("1"))
hashedCredentialsMatcher
.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);
else if (hashAlgorithm.equals("2"))
throw new AuthenticationException(
"Requested 'Blowfish' algorithm is not
supported. Can not validate the token.");
else if (hashAlgorithm.equals("2a"))
throw new AuthenticationException(
"Requested 'eksblowfish' algorithm is
not supported. Can not validate the token.");
setCredentialsMatcher(credentialsMatcher);
// Hex decoding is ugly and should not be used
really
salt =
hashedCredentialsMatcher.isStoredCredentialsHexEncoded()
? new String(Hex.decode(crypt[2]))
: Base64.decodeToString(crypt[2]);
password = crypt[3];
break;
default:
throw new AuthenticationException(
"Unable to parse 'crypt' from password. Can
not validate the token.");
}
}
break;
case COLUMN:
String[] queryResults = getPasswordForUser(conn, username);
password = queryResults[0];
salt = queryResults[1];
break;
case EXTERNAL:
password = getPasswordForUser(conn, username)[0];
salt = getSaltForUser(username);
}
if (password == null) {
throw new UnknownAccountException("No account found for user [" +
username + "]");
}
info = new SimpleAuthenticationInfo(username, password.toCharArray(),
getName());
if (salt != null) {
info.setCredentialsSalt(ByteSource.Util.bytes(salt));
}
} catch (SQLException e) {
final String message =
"There was a SQL error while authenticating user [" + username
+ "]";
LOGGER.log(Level.SEVERE, message, e);
// Rethrow any SQL errors as an authentication exception
throw new AuthenticationException(message, e);
} finally {
JdbcUtils.closeConnection(conn);
}
return info;
}
On Tue, 2025-10-21 at 21:15 -0500, [email protected] wrote:
> Thanks for your quick response.
> Just to clarify, your records in the password database look something
> like this:
>
> $shiro2$2y$10$EiVaDycDiJG1O24MqXb6F.42YtW.3VDpMAwDkC0N8JZehp52o9q32
>
> Is that correct?
>
> > On Oct 21, 2025, at 7:58 PM, Andreas Reichel <andreas@manticore-
> > projects.com> wrote:
> >
> >
> > On Tue, 2025-10-21 at 13:26 -0500, [email protected] wrote:
> > > Hi,
> > >
> > > Just taking a quick survey if anyone is using BCrypt (2y) etc.
> > > algorithm.
> > > It’s currently very difficult to use and should be renamed to
> > > bcrypt2y, etc.
> > >
> > > Thank you.
> >
> >
> >
> > Greetings Lenni and Team,
> >
> > yes we do since our database solution stores in BCrypt format.
> >
> > Cheers and best
> > Andreas
>