public class HashedCredentialsMatcher extends SimpleCredentialsMatcher
HashedCredentialMatcher
provides support for hashing of supplied AuthenticationToken
credentials
before being compared to those in the AuthenticationInfo
from the data store.
Credential hashing is one of the most common security techniques when safeguarding a user's private credentials
(passwords, keys, etc). Most developers never want to store their users' credentials in plain form, viewable by
anyone, so they often hash the users' credentials before they are saved in the data store.
This class (and its subclasses) function as follows:
AuthenticationToken
credentials supplied by the user during their login.AuthenticationInfo
credentials stored in the system
(the stored account credentials are expected to already be in hashed form).equal
, the submitted credentials match, otherwise
they do not.Md5Hash
,
Sha1Hash
, etc) support salting and multiple hash iterations via
overloaded constructors.
AuthenticationToken
via the now-deprecated
getSalt(AuthenticationToken)
method. This however
could constitute a security hole since ideally salts should never be obtained based on what a user can submit.
User-submitted salt mechanisms are much more susceptible to dictionary attacks and SHOULD NOT be
used in secure systems. Instead salts should ideally be a secure randomly-generated number that is generated when
the user account is created. The secure number should never be disseminated to the user and always kept private
by the application.
AuthenticationInfo
instance). This is much
more secure because the salt value remains private to the application (Shiro will never store this value).
To enable this, Realm
s should return SaltedAuthenticationInfo
instances
during authentication. HashedCredentialsMatcher
implementations will then use the provided
credentialsSalt
for hashing. To avoid
security risks,
it is highly recommended that any existing Realm
implementations that support hashed credentials are
updated to return SaltedAuthenticationInfo
instances as soon as possible.
Realm
implementations that support credentials hashing should
be updated to return SaltedAuthenticationInfo
instances as
soon as possible.
If this is not possible for some reason, this class will retain 1.0 backwards-compatible behavior of obtaining
the salt via the now-deprecated getSalt(AuthenticationToken)
method. This
method will only be invoked if a Realm
does not return
SaltedAutenticationInfo
instances and hashSalted
is
true
.
But please note that the hashSalted
property and the
getSalt(AuthenticationToken)
methods will be removed before the Shiro 2.0
release.
hashIterations
property. See the
Hashing Java article's
"Hardening against the attacker's attack" section to learn more about why you might want to use
multiple hash iterations.
CredentialsMatcher
implementations.Md5Hash
,
Sha1Hash
,
Sha256Hash
PREFERRED_ENCODING
Constructor and Description |
---|
HashedCredentialsMatcher()
JavaBeans-compatible no-arg constructor intended for use in IoC/Dependency Injection environments.
|
HashedCredentialsMatcher(String hashAlgorithmName)
Creates an instance using the specified
hashAlgorithmName to hash submitted
credentials. |
Modifier and Type | Method and Description |
---|---|
boolean |
doCredentialsMatch(AuthenticationToken token,
AuthenticationInfo info)
This implementation first hashes the
token 's credentials, potentially using a
salt if the info argument is a
SaltedAuthenticationInfo . |
protected Object |
getCredentials(AuthenticationInfo info)
Returns a
Hash instance representing the already-hashed AuthenticationInfo credentials stored in the system. |
String |
getHashAlgorithmName()
Returns the
Hash algorithmName to use
when performing hashes for credentials matching. |
int |
getHashIterations()
Returns the number of times a submitted
AuthenticationToken 's credentials will be hashed before
comparing to the credentials stored in the system. |
protected Object |
getSalt(AuthenticationToken token)
Deprecated.
since Shiro 1.1. Hash salting is now expected to be based on if the
AuthenticationInfo
returned from the Realm is a SaltedAuthenticationInfo instance and its
getCredentialsSalt() method returns a non-null value.
This method and the 1.0 behavior still exists for backwards compatibility if the Realm does not return
SaltedAuthenticationInfo instances, but it is highly recommended that Realm implementations
that support hashed credentials start returning SaltedAuthenticationInfo
instances as soon as possible.
This is because salts should always be obtained from the stored account information and
never be interpreted based on user/Subject-entered data. User-entered data is easier to compromise for
attackers, whereas account-unique (and secure randomly-generated) salts never disseminated to the end-user
are almost impossible to break. This method will be removed in Shiro 2.0. |
protected Object |
hashProvidedCredentials(AuthenticationToken token,
AuthenticationInfo info)
Hash the provided
token 's credentials using the salt stored with the account if the
info instance is an instanceof SaltedAuthenticationInfo (see
the class-level JavaDoc for why this is the preferred approach). |
protected Hash |
hashProvidedCredentials(Object credentials,
Object salt,
int hashIterations)
Hashes the provided credentials a total of
hashIterations times, using the given salt. |
boolean |
isHashSalted()
Deprecated.
since Shiro 1.1. Hash salting is now expected to be based on if the
AuthenticationInfo
returned from the Realm is a SaltedAuthenticationInfo instance and its
getCredentialsSalt() method returns a non-null value.
This method and the 1.0 behavior still exists for backwards compatibility if the Realm does not return
SaltedAuthenticationInfo instances, but it is highly recommended that Realm implementations
that support hashed credentials start returning SaltedAuthenticationInfo
instances as soon as possible.
This is because salts should always be obtained from the stored account information and
never be interpreted based on user/Subject-entered data. User-entered data is easier to compromise for
attackers, whereas account-unique (and secure randomly-generated) salts never disseminated to the end-user
are almost impossible to break. This method will be removed in Shiro 2.0. |
boolean |
isStoredCredentialsHexEncoded()
Returns
true if the system's stored credential hash is Hex encoded, false if it
is Base64 encoded. |
protected AbstractHash |
newHashInstance()
Returns a new, uninitialized instance, without its byte array set.
|
void |
setHashAlgorithmName(String hashAlgorithmName)
Sets the
Hash algorithmName to use
when performing hashes for credentials matching. |
void |
setHashIterations(int hashIterations)
Sets the number of times a submitted
AuthenticationToken 's credentials will be hashed before comparing
to the credentials stored in the system. |
void |
setHashSalted(boolean hashSalted)
Deprecated.
since Shiro 1.1. Hash salting is now expected to be based on if the
AuthenticationInfo
returned from the Realm is a SaltedAuthenticationInfo instance and its
getCredentialsSalt() method returns a non-null value.
This method and the 1.0 behavior still exists for backwards compatibility if the Realm does not return
SaltedAuthenticationInfo instances, but it is highly recommended that Realm implementations
that support hashed credentials start returning SaltedAuthenticationInfo
instances as soon as possible.
This is because salts should always be obtained from the stored account information and
never be interpreted based on user/Subject-entered data. User-entered data is easier to compromise for
attackers, whereas account-unique (and secure randomly-generated) salts never disseminated to the end-user
are almost impossible to break. This method will be removed in Shiro 2.0. |
void |
setStoredCredentialsHexEncoded(boolean storedCredentialsHexEncoded)
Sets the indicator if this system's stored credential hash is Hex encoded or not.
|
equals, getCredentials
isByteSource, objectToBytes, objectToString, toBytes, toBytes, toBytes, toBytes, toBytes, toBytes, toBytes, toChars, toChars, toString, toString, toString
public HashedCredentialsMatcher()
hashAlgorithmName
property.public HashedCredentialsMatcher(String hashAlgorithmName)
hashAlgorithmName
to hash submitted
credentials.hashAlgorithmName
- the Hash
algorithmName
to use when performing hashes for credentials matching.public String getHashAlgorithmName()
Hash
algorithmName
to use
when performing hashes for credentials matching.Hash
algorithmName
to use
when performing hashes for credentials matching.public void setHashAlgorithmName(String hashAlgorithmName)
Hash
algorithmName
to use
when performing hashes for credentials matching.hashAlgorithmName
- the Hash
algorithmName
to use when performing hashes for credentials matching.public boolean isStoredCredentialsHexEncoded()
true
if the system's stored credential hash is Hex encoded, false
if it
is Base64 encoded.
Default value is true
for convenience - all of Shiro's Hash#toString()
implementations return Hex encoded values by default, making this class's use with those implementations
easier.true
if the system's stored credential hash is Hex encoded, false
if it
is Base64 encoded. Default is true
public void setStoredCredentialsHexEncoded(boolean storedCredentialsHexEncoded)
true
will cause this class to decode the system credential from Hex, a
value of false
will cause this class to decode the system credential from Base64.
Unless overridden via this method, the default value is true
for convenience - all of Shiro's
Hash#toString()
implementations return Hex encoded values by default, making this class's use with
those implementations easier.storedCredentialsHexEncoded
- the indicator if this system's stored credential hash is Hex
encoded or not ('not' automatically implying it is Base64 encoded).@Deprecated public boolean isHashSalted()
AuthenticationInfo
returned from the Realm
is a SaltedAuthenticationInfo
instance and its
getCredentialsSalt()
method returns a non-null value.
This method and the 1.0 behavior still exists for backwards compatibility if the Realm
does not return
SaltedAuthenticationInfo
instances, but it is highly recommended that Realm
implementations
that support hashed credentials start returning SaltedAuthenticationInfo
instances as soon as possible.
This is because salts should always be obtained from the stored account information and
never be interpreted based on user/Subject-entered data. User-entered data is easier to compromise for
attackers, whereas account-unique (and secure randomly-generated) salts never disseminated to the end-user
are almost impossible to break. This method will be removed in Shiro 2.0.true
if a submitted AuthenticationToken
's credentials should be salted when hashing,
false
if it should not be salted.
If enabled, the salt used will be obtained via the getSalt
method.
The default value is false
.true
if a submitted AuthenticationToken
's credentials should be salted when hashing,
false
if it should not be salted.@Deprecated public void setHashSalted(boolean hashSalted)
AuthenticationInfo
returned from the Realm
is a SaltedAuthenticationInfo
instance and its
getCredentialsSalt()
method returns a non-null value.
This method and the 1.0 behavior still exists for backwards compatibility if the Realm
does not return
SaltedAuthenticationInfo
instances, but it is highly recommended that Realm
implementations
that support hashed credentials start returning SaltedAuthenticationInfo
instances as soon as possible.
This is because salts should always be obtained from the stored account information and
never be interpreted based on user/Subject-entered data. User-entered data is easier to compromise for
attackers, whereas account-unique (and secure randomly-generated) salts never disseminated to the end-user
are almost impossible to break. This method will be removed in Shiro 2.0.AuthenticationToken
's credentials when hashing.
If enabled, the salt used will be obtained via the getCredentialsSalt
method.
The default value is false
.hashSalted
- whether or not to salt a submitted AuthenticationToken
's credentials when hashing.public int getHashIterations()
AuthenticationToken
's credentials will be hashed before
comparing to the credentials stored in the system.
Unless overridden, the default value is 1
, meaning a normal hash execution will occur.AuthenticationToken
's credentials will be hashed before
comparing to the credentials stored in the system.public void setHashIterations(int hashIterations)
AuthenticationToken
's credentials will be hashed before comparing
to the credentials stored in the system.
Unless overridden, the default value is 1
, meaning a normal single hash execution will occur.
If this argument is less than 1 (i.e. 0 or negative), the default value of 1 is applied. There must always be
at least 1 hash iteration (otherwise there would be no hash).hashIterations
- the number of times to hash a submitted AuthenticationToken
's credentials.@Deprecated protected Object getSalt(AuthenticationToken token)
AuthenticationInfo
returned from the Realm
is a SaltedAuthenticationInfo
instance and its
getCredentialsSalt()
method returns a non-null value.
This method and the 1.0 behavior still exists for backwards compatibility if the Realm
does not return
SaltedAuthenticationInfo
instances, but it is highly recommended that Realm
implementations
that support hashed credentials start returning SaltedAuthenticationInfo
instances as soon as possible.
This is because salts should always be obtained from the stored account information and
never be interpreted based on user/Subject-entered data. User-entered data is easier to compromise for
attackers, whereas account-unique (and secure randomly-generated) salts never disseminated to the end-user
are almost impossible to break. This method will be removed in Shiro 2.0.token.getPrincipal()
, effectively using the user's
identity (username, user id, etc) as the salt, a most common technique. If you wish to provide the
authentication token's salt another way, you may override this method.token
- the AuthenticationToken submitted during the authentication attempt.protected Object getCredentials(AuthenticationInfo info)
Hash
instance representing the already-hashed AuthenticationInfo credentials stored in the system.
This method reconstructs a Hash
instance based on a info.getCredentials
call,
but it does not hash that value - it is expected that method call will return an already-hashed value.
This implementation's reconstruction effort functions as follows:
account.getCredentials()
to a byte array via the toBytes
method.
account.getCredentials()
was originally a String or char[] before toBytes
was
called, check for encoding:
storedCredentialsHexEncoded
, Hex decode that byte array, otherwise
Base64 decode the byte arrayHash
implementation and return it.getCredentials
in class SimpleCredentialsMatcher
info
- the AuthenticationInfo from which to retrieve the credentials which assumed to be in already-hashed form.Hash
instance representing the given AuthenticationInfo's stored credentials.public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info)
token
's credentials, potentially using a
salt
if the info
argument is a
SaltedAuthenticationInfo
. It then compares the hash
against the AuthenticationInfo
's
already-hashed credentials
. This method
returns true
if those two values are equal
, false
otherwise.doCredentialsMatch
in interface CredentialsMatcher
doCredentialsMatch
in class SimpleCredentialsMatcher
token
- the AuthenticationToken
submitted during the authentication attempt.info
- the AuthenticationInfo
stored in the system matching the token principaltrue
if the provided token credentials hash match to the stored account credentials hash,
false
otherwiseprotected Object hashProvidedCredentials(AuthenticationToken token, AuthenticationInfo info)
token
's credentials using the salt stored with the account if the
info
instance is an instanceof
SaltedAuthenticationInfo
(see
the class-level JavaDoc for why this is the preferred approach).
If the info
instance is not
an instanceof
SaltedAuthenticationInfo
, the logic will fall back to Shiro 1.0
backwards-compatible logic: it will first check to see isHashSalted
and if so, will try
to acquire the salt from getSalt(AuthenticationToken)
. See the class-level
JavaDoc for why this is not recommended. This 'fallback' logic exists only for backwards-compatibility.
Realm
s should be updated as soon as possible to return SaltedAuthenticationInfo
instances
if account credentials salting is enabled (highly recommended for password-based systems).token
- the submitted authentication token from which its credentials will be hashedinfo
- the stored account data, potentially used to acquire a saltprotected Hash hashProvidedCredentials(Object credentials, Object salt, int hashIterations)
hashIterations
times, using the given salt. The hash
implementation/algorithm used is based on the hashAlgorithmName
property.credentials
- the submitted authentication token's credentials to hashsalt
- the value to salt the hash, or null
if a salt will not be used.hashIterations
- the number of times to hash the credentials. At least one hash will always occur though,
even if this argument is 0 or negative.protected AbstractHash newHashInstance()
getCredentials(AuthenticationInfo)
implementation.Copyright © 2004–2020 The Apache Software Foundation. All rights reserved.