A {@code HashedCredentialMatcher} provides support for hashing of supplied {@code AuthenticationToken} credentials before being compared to those in the {@code AuthenticationInfo} from the data store. <p/> 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. <p/> This class (and its subclasses) function as follows: <ol> <li>Hash the {@code AuthenticationToken} credentials supplied by the user during their login.</li> <li>Compare this hashed value directly with the {@code AuthenticationInfo} credentials stored in the system (the stored account credentials are expected to already be in hashed form).</li> <li>If these two values are {@link #equals(Object, Object) equal}, the submitted credentials match, otherwise they do not.</li> </ol> <h2>Salting and Multiple Hash Iterations</h2> Because simple hashing is usually not good enough for secure applications, this class also supports 'salting' and multiple hash iterations. Please read this excellent <a href="http://www.owasp.org/index.php/Hashing_Java" _target="blank">Hashing Java article</a> to learn about salting and multiple iterations and why you might want to use them. (Note of sections 5 "Why add salt?" and 6 "Hardening against the attacker's attack"). We should also note here that all of Shiro's Hash implementations (for example, {@link hunt.shiro.crypto.hash.Md5Hash Md5Hash}, {@link hunt.shiro.crypto.hash.Sha1Hash Sha1Hash}, etc) support salting and multiple hash iterations via overloaded constructors. <h4>Real World Case Study</h4> In April 2010, some public Atlassian Jira and Confluence installations (Apache Software Foundation, Codehaus, etc) were the target of account attacks and user accounts were compromised. The reason? Jira and Confluence at the time did not salt user passwords and attackers were able to use dictionary attacks to compromise user accounts (Atlassian has since <a href="http://blogs.atlassian.com/news/2010/04/oh_man_what_a_day_an_update_on_our_security_breach.html"> fixed the problem</a> of course). <p/> The lesson? <p/> <b>ALWAYS, ALWAYS, ALWAYS SALT USER PASSWORDS!</b> <p/> <h3>Salting</h3> Prior to Shiro 1.1, salts could be obtained based on the end-user submitted {@link AuthenticationToken AuthenticationToken} via the now-deprecated {@link #getSalt(hunt.shiro.authc.AuthenticationToken) 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 <em>much</em> more susceptible to dictionary attacks and <b>SHOULD NOT</b> 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. <h4>Shiro 1.1</h4> As of Shiro 1.1, it is expected that any salt used to hash the submitted credentials will be obtained from the stored account information (represented as an {@link AuthenticationInfo AuthenticationInfo} instance). This is much more secure because the salt value remains private to the application (Shiro will never store this value). <p/> To enable this, {@code Realm}s should return {@link SaltedAuthenticationInfo SaltedAuthenticationInfo} instances during authentication. {@code HashedCredentialsMatcher} implementations will then use the provided {@link hunt.shiro.authc.SaltedAuthenticationInfo#getCredentialsSalt credentialsSalt} for hashing. To avoid security risks, <b>it is highly recommended that any existing {@code Realm} implementations that support hashed credentials are updated to return {@link SaltedAuthenticationInfo SaltedAuthenticationInfo} instances as soon as possible</b>. <h4>Shiro 1.0 Backwards Compatibility</h4> Because of the identified security risk, {@code Realm} implementations that support credentials hashing should be updated to return {@link SaltedAuthenticationInfo SaltedAuthenticationInfo} instances as soon as possible. <p/> 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 {@link #getSalt(AuthenticationToken) getSalt(AuthenticationToken)} method. This method will only be invoked if a {@code Realm} <em>does not</em> return {@link SaltedAuthenticationInfo SaltedAutenticationInfo} instances and {@link #isHashSalted() hashSalted} is {@code true}. But please note that the {@link #isHashSalted() hashSalted} property and the {@link #getSalt(AuthenticationToken) getSalt(AuthenticationToken)} methods will be removed before the Shiro 2.0 release. <h3>Multiple Hash Iterations</h3> If you hash your users' credentials multiple times before persisting to the data store, you will also need to set this class's {@link #setHashIterations(int) hashIterations} property. See the <a href="http://www.owasp.org/index.php/Hashing_Java" _target="blank">Hashing Java article</a>'s <a href="http://www.owasp.org/index.php/Hashing_Java#Hardening_against_the_attacker.27s_attack"> "Hardening against the attacker's attack"</a> section to learn more about why you might want to use multiple hash iterations. <h2>MD5 & SHA-1 Notice</h2> <a href="http://en.wikipedia.org/wiki/MD5">MD5</a> and <a href="http://en.wikipedia.org/wiki/SHA_hash_functions">SHA-1</a> algorithms are now known to be vulnerable to compromise and/or collisions (read the linked pages for more). While most applications are ok with either of these two, if your application mandates high security, use the SHA-256 (or higher) hashing algorithms and their supporting {@code CredentialsMatcher} implementations.