protected boolean equals(Object tokenCredentials, Object accountCredentials) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Performing credentials equality check for tokenCredentials of type ["
                    + tokenCredentials.getClass().getName() + " and accountCredentials of type ["
                    + accountCredentials.getClass().getName() + "]");
        }
        if (isByteSource(tokenCredentials) && isByteSource(accountCredentials)) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Both credentials arguments can be easily converted to byte arrays.  Performing "
                        + "array equals comparison");
            }
            byte[] tokenBytes = toBytes(tokenCredentials);
            byte[] accountBytes = toBytes(accountCredentials);
            return MessageDigest.isEqual(tokenBytes, accountBytes);
        } else {
            return accountCredentials.equals(tokenCredentials);
        }
    }
Returns {@code true} if the {@code tokenCredentials} argument is logically equal to the
{@code accountCredentials} argument.
<p/>
<p>If both arguments are either a byte array (byte[]), char array (char[]) or String, they will be both be
converted to raw byte arrays via the {@link #toBytes toBytes} method first, and then resulting byte arrays
are compared via {@link Arrays#equals(byte[], byte[]) Arrays.equals(byte[],byte[])}.</p>
<p/>
<p>If either argument cannot be converted to a byte array as described, a simple Object <code>equals</code>
comparison is made.</p>
<p/>
<p>Subclasses should override this method for more explicit equality checks.

@param tokenCredentials   the {@code AuthenticationToken}'s associated credentials.
@param accountCredentials the {@code AuthenticationInfo}'s stored credentials.
@return {@code true} if the {@code tokenCredentials} are equal to the {@code accountCredentials}.
core/src/main/java/org/apache/shiro/authc/credential/SimpleCredentialsMatcher.java