DefaultHashService

Default implementation of the {@link HashService} interface, supporting a customizable hash algorithm name, secure-random salt generation, multiple hash iterations and an optional internal {@link #setPrivateSalt(ByteSource) privateSalt}. <h2>Hash Algorithm</h2> You may specify a hash algorithm via the {@link #setHashAlgorithmName(string)} property. Any algorithm name understood by the JDK {@link java.security.MessageDigest#getInstance(string) MessageDigest.getInstance(string algorithmName)} method will work. The default is {@code SHA-512}. <h2>Random Salts</h2> When a salt is not specified in a request, this implementation generates secure random salts via its {@link #setRandomNumberGenerator(hunt.shiro.crypto.RandomNumberGenerator) randomNumberGenerator} property. Random salts (and potentially combined with the internal {@link #getPrivateSalt() privateSalt}) is a very strong salting strategy, as salts should ideally never be based on known/guessable data. The default instance is a {@link SecureRandomNumberGenerator}. <h2>Hash Iterations</h2> Secure hashing strategies often employ multiple hash iterations to slow down the hashing process. This technique is usually used for password hashing, since the longer it takes to compute a password hash, the longer it would take for an attacker to compromise a password. This <a href="http://www.stormpath.com/blog/strong-password-hashing-apache-shiro">blog article</a> explains in greater detail why this is useful, as well as information on how many iterations is 'enough'. <p/> You may set the number of hash iterations via the {@link #setHashIterations(int)} property. The default is {@code 1}, but should be increased significantly if the {@code HashService} is intended to be used for password hashing. See the linked blog article for more info. <h2>Private Salt</h2> If using this implementation as part of a password hashing strategy, it might be desirable to configure a {@link #setPrivateSalt(ByteSource) private salt}: <p/> A hash and the salt used to compute it are often stored together. If an attacker is ever able to access the hash (e.g. during password cracking) and it has the full salt value, the attacker has all of the input necessary to try to brute-force crack the hash (source + complete salt). <p/> However, if part of the salt is not available to the attacker (because it is not stored with the hash), it is <em>much</em> harder to crack the hash value since the attacker does not have the complete inputs necessary. <p/> The {@link #getPrivateSalt() privateSalt} property exists to satisfy this private-and-not-shared part of the salt. If you configure this attribute, you can obtain this additional very important safety feature. <p/> <b>*</b>By default, the {@link #getPrivateSalt() privateSalt} is null, since a sensible default cannot be used that isn't easily compromised (because Shiro is an open-source project and any default could be easily seen and used).

Constructors

this
this()

Constructs a new {@code DefaultHashService} instance with the following defaults: <ul> <li>{@link #setHashAlgorithmName(string) hashAlgorithmName} = {@code SHA-512}</li> <li>{@link #setHashIterations(int) hashIterations} = {@code 1}</li> <li>{@link #setRandomNumberGenerator(hunt.shiro.crypto.RandomNumberGenerator) randomNumberGenerator} = new {@link SecureRandomNumberGenerator}()</li> <li>{@link #setGeneratePublicSalt(bool) generatePublicSalt} = {@code false}</li> </ul> <p/> If this hashService will be used for password hashing it is recommended to set the {@link #setPrivateSalt(ByteSource) privateSalt} and significantly increase the number of {@link #setHashIterations(int) hashIterations}. See the class-level JavaDoc for more information.

Members

Functions

combine
ByteSource combine(ByteSource privateSalt, ByteSource publicSalt)

Combines the specified 'private' salt bytes with the specified additional extra bytes to use as the total salt during hash computation. {@code privateSaltBytes} will be {@code null} }if no private salt has been configured.

computeHash
Hash computeHash(HashRequest request)

Computes and responds with a hash based on the specified request. <p/> This implementation functions as follows: <ul> <li>If the request's {@link hunt.shiro.crypto.hash.HashRequest#getSalt() salt} is null: <p/> A salt will be generated and used to compute the hash. The salt is generated as follows: <ol> <li>Use the {@link #getRandomNumberGenerator() randomNumberGenerator} to generate a new random number.</li> <li>{@link #combine(ByteSource, ByteSource) combine} this random salt with any configured {@link #getPrivateSalt() privateSalt} </li> <li>Use the combined value as the salt used during hash computation</li> </ol> </li> <li> If the request salt is not null: <p/> This indicates that the hash computation is for comparison purposes (of a previously computed hash). The request salt will be {@link #combine(ByteSource, ByteSource) combined} with any configured {@link #getPrivateSalt() privateSalt} and used as the complete salt during hash computation. </li> </ul> <p/> The returned {@code Hash}'s {@link Hash#getSalt() salt} property will contain <em>only</em> the 'public' part of the salt and <em>NOT</em> the privateSalt. See the class-level JavaDoc explanation for more info.

getAlgorithmName
string getAlgorithmName(HashRequest request)
Undocumented in source. Be warned that the author may not have intended to support it.
getHashAlgorithmName
string getHashAlgorithmName()
Undocumented in source. Be warned that the author may not have intended to support it.
getHashIterations
int getHashIterations()
Undocumented in source. Be warned that the author may not have intended to support it.
getIterations
int getIterations(HashRequest request)
Undocumented in source. Be warned that the author may not have intended to support it.
getPrivateSalt
ByteSource getPrivateSalt()
Undocumented in source. Be warned that the author may not have intended to support it.
getPublicSalt
ByteSource getPublicSalt(HashRequest request)

Returns the public salt that should be used to compute a hash based on the specified request or {@code null} if no public salt should be used. <p/> This implementation functions as follows: <ol> <li>If the request salt is not null and non-empty, this will be used, return it.</li> <li>If the request salt is null or empty: <ol> <li>If a private salt has been set <em>OR</em> {@link #isGeneratePublicSalt()} is {@code true}, auto generate a random public salt via the configured {@link #getRandomNumberGenerator() randomNumberGenerator}.</li> <li>If a private salt has not been configured and {@link #isGeneratePublicSalt()} is {@code false}, do nothing - return {@code null} to indicate a salt should not be used during hash computation.</li> </ol> </li> </ol>

getRandomNumberGenerator
RandomNumberGenerator getRandomNumberGenerator()
Undocumented in source. Be warned that the author may not have intended to support it.
isGeneratePublicSalt
bool isGeneratePublicSalt()

Returns {@code true} if a public salt should be randomly generated and used to compute a hash if a {@link HashRequest} does not specify a salt, {@code false} otherwise. <p/> The default value is {@code false} but should definitely be set to {@code true} if the {@code HashService} instance is being used for password hashing. <p/> <b>NOTE:</b> this property only has an effect if a {@link #getPrivateSalt() privateSalt} is NOT configured. If a private salt has been configured and a request does not provide a salt, a random salt will always be generated to protect the integrity of the private salt (without a public salt, the private salt would be exposed as-is, which is undesirable).

setGeneratePublicSalt
void setGeneratePublicSalt(bool generatePublicSalt)

Sets whether or not a public salt should be randomly generated and used to compute a hash if a {@link HashRequest} does not specify a salt. <p/> The default value is {@code false} but should definitely be set to {@code true} if the {@code HashService} instance is being used for password hashing. <p/> <b>NOTE:</b> this property only has an effect if a {@link #getPrivateSalt() privateSalt} is NOT configured. If a private salt has been configured and a request does not provide a salt, a random salt will always be generated to protect the integrity of the private salt (without a public salt, the private salt would be exposed as-is, which is undesirable).

setHashAlgorithmName
void setHashAlgorithmName(string name)
Undocumented in source. Be warned that the author may not have intended to support it.
setHashIterations
void setHashIterations(int count)
Undocumented in source. Be warned that the author may not have intended to support it.
setPrivateSalt
void setPrivateSalt(ByteSource privateSalt)
Undocumented in source. Be warned that the author may not have intended to support it.
setRandomNumberGenerator
void setRandomNumberGenerator(RandomNumberGenerator rng)
Undocumented in source. Be warned that the author may not have intended to support it.

Inherited Members

From ConfigurableHashService

setPrivateSalt
void setPrivateSalt(ByteSource privateSalt)

Sets the 'private' (internal) salt to be paired with a 'public' (random or supplied) salt during hash computation.

setHashIterations
void setHashIterations(int iterations)

Sets the number of hash iterations that will be performed during hash computation.

setHashAlgorithmName
void setHashAlgorithmName(string name)

Sets the name of the {@link java.security.MessageDigest MessageDigest} algorithm that will be used to compute hashes.

setRandomNumberGenerator
void setRandomNumberGenerator(RandomNumberGenerator rng)

Sets a source of randomness used to generate public salts that will in turn be used during hash computation.

Meta