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
> 

Reply via email to