org.apache.shiro.crypto.hash
Class DefaultHashService

java.lang.Object
  extended by org.apache.shiro.crypto.hash.DefaultHashService
All Implemented Interfaces:
ConfigurableHashService, HashService

public class DefaultHashService
extends Object
implements ConfigurableHashService

Default implementation of the HashService interface, supporting a customizable hash algorithm name, secure-random salt generation, multiple hash iterations and an optional internal privateSalt.

Hash Algorithm

You may specify a hash algorithm via the setHashAlgorithmName(String) property. Any algorithm name understood by the JDK MessageDigest.getInstance(String algorithmName) method will work. The default is SHA-512.

Random Salts

When a salt is not specified in a request, this implementation generates secure random salts via its randomNumberGenerator property. Random salts (and potentially combined with the internal privateSalt) is a very strong salting strategy, as salts should ideally never be based on known/guessable data. The default instance is a SecureRandomNumberGenerator.

Hash Iterations

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 Katasoft blog article explains in greater detail why this is useful, as well as information on how many iterations is 'enough'.

You may set the number of hash iterations via the setHashIterations(int) property. The default is 1, but should be increased significantly if the HashService is intended to be used for password hashing. See the linked blog article for more info.

Private Salt

If using this implementation as part of a password hashing strategy, it might be desirable to configure a private salt:

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).

However, if part of the salt is not available to the attacker (because it is not stored with the hash), it is much harder to crack the hash value since the attacker does not have the complete inputs necessary.

The 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.

*By default, the 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).

Since:
1.2

Constructor Summary
DefaultHashService()
          Constructs a new DefaultHashService instance with the following defaults: hashAlgorithmName = SHA-512 hashIterations = 1 randomNumberGenerator = new SecureRandomNumberGenerator() generatePublicSalt = false

If this hashService will be used for password hashing it is recommended to set the privateSalt and significantly increase the number of hashIterations.

 
Method Summary
protected  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.
 Hash computeHash(HashRequest request)
          Computes and responds with a hash based on the specified request.
protected  String getAlgorithmName(HashRequest request)
           
 String getHashAlgorithmName()
           
 int getHashIterations()
           
protected  int getIterations(HashRequest request)
           
 ByteSource getPrivateSalt()
           
protected  ByteSource getPublicSalt(HashRequest request)
          Returns the public salt that should be used to compute a hash based on the specified request or null if no public salt should be used.
 RandomNumberGenerator getRandomNumberGenerator()
           
 boolean isGeneratePublicSalt()
          Returns true if a public salt should be randomly generated and used to compute a hash if a HashRequest does not specify a salt, false otherwise.
 void setGeneratePublicSalt(boolean generatePublicSalt)
          Sets whether or not a public salt should be randomly generated and used to compute a hash if a HashRequest does not specify a salt.
 void setHashAlgorithmName(String name)
          Sets the name of the MessageDigest algorithm that will be used to compute hashes.
 void setHashIterations(int count)
          Sets the number of hash iterations that will be performed during hash computation.
 void setPrivateSalt(ByteSource privateSalt)
          Sets the 'private' (internal) salt to be paired with a 'public' (random or supplied) salt during hash computation.
 void setRandomNumberGenerator(RandomNumberGenerator rng)
          Sets a source of randomness used to generate public salts that will in turn be used during hash computation.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DefaultHashService

public DefaultHashService()
Constructs a new DefaultHashService instance with the following defaults:

If this hashService will be used for password hashing it is recommended to set the privateSalt and significantly increase the number of hashIterations. See the class-level JavaDoc for more information.

Method Detail

computeHash

public Hash computeHash(HashRequest request)
Computes and responds with a hash based on the specified request.

This implementation functions as follows:

The returned Hash's salt property will contain only the 'public' part of the salt and NOT the privateSalt. See the class-level JavaDoc explanation for more info.

Specified by:
computeHash in interface HashService
Parameters:
request - the request to process
Returns:
the response containing the result of the hash computation, as well as any hash salt used that should be exposed to the caller.
See Also:
Hash.getSalt()

getAlgorithmName

protected String getAlgorithmName(HashRequest request)

getIterations

protected int getIterations(HashRequest request)

getPublicSalt

protected ByteSource getPublicSalt(HashRequest request)
Returns the public salt that should be used to compute a hash based on the specified request or null if no public salt should be used.

This implementation functions as follows:

  1. If the request salt is not null and non-empty, this will be used, return it.
  2. If the request salt is null or empty:
    1. If a private salt has been set OR isGeneratePublicSalt() is true, auto generate a random public salt via the configured randomNumberGenerator.
    2. If a private salt has not been configured and isGeneratePublicSalt() is false, do nothing - return null to indicate a salt should not be used during hash computation.

Parameters:
request - request the request to process
Returns:
the public salt that should be used to compute a hash based on the specified request or null if no public salt should be used.

combine

protected 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. privateSaltBytes will be null }if no private salt has been configured.

Parameters:
privateSalt - the (possibly null) 'private' salt to combine with the specified extra bytes
publicSalt - the extra bytes to use in addition to the given private salt.
Returns:
a combination of the specified private salt bytes and extra bytes that will be used as the total salt during hash computation.

setHashAlgorithmName

public void setHashAlgorithmName(String name)
Description copied from interface: ConfigurableHashService
Sets the name of the MessageDigest algorithm that will be used to compute hashes.

Specified by:
setHashAlgorithmName in interface ConfigurableHashService
Parameters:
name - the name of the MessageDigest algorithm that will be used to compute hashes.

getHashAlgorithmName

public String getHashAlgorithmName()

setPrivateSalt

public void setPrivateSalt(ByteSource privateSalt)
Description copied from interface: ConfigurableHashService
Sets the 'private' (internal) salt to be paired with a 'public' (random or supplied) salt during hash computation.

Specified by:
setPrivateSalt in interface ConfigurableHashService
Parameters:
privateSalt - the 'private' internal salt to be paired with a 'public' (random or supplied) salt during hash computation.

getPrivateSalt

public ByteSource getPrivateSalt()

setHashIterations

public void setHashIterations(int count)
Description copied from interface: ConfigurableHashService
Sets the number of hash iterations that will be performed during hash computation.

Specified by:
setHashIterations in interface ConfigurableHashService
Parameters:
count - the number of hash iterations that will be performed during hash computation.

getHashIterations

public int getHashIterations()

setRandomNumberGenerator

public void setRandomNumberGenerator(RandomNumberGenerator rng)
Description copied from interface: ConfigurableHashService
Sets a source of randomness used to generate public salts that will in turn be used during hash computation.

Specified by:
setRandomNumberGenerator in interface ConfigurableHashService
Parameters:
rng - a source of randomness used to generate public salts that will in turn be used during hash computation.

getRandomNumberGenerator

public RandomNumberGenerator getRandomNumberGenerator()

isGeneratePublicSalt

public boolean isGeneratePublicSalt()
Returns true if a public salt should be randomly generated and used to compute a hash if a HashRequest does not specify a salt, false otherwise.

The default value is false but should definitely be set to true if the HashService instance is being used for password hashing.

NOTE: this property only has an effect if a 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).

Returns:
true if a public salt should be randomly generated and used to compute a hash if a HashRequest does not specify a salt, false otherwise.

setGeneratePublicSalt

public void setGeneratePublicSalt(boolean generatePublicSalt)
Sets whether or not a public salt should be randomly generated and used to compute a hash if a HashRequest does not specify a salt.

The default value is false but should definitely be set to true if the HashService instance is being used for password hashing.

NOTE: this property only has an effect if a 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).

Parameters:
generatePublicSalt - whether or not a public salt should be randomly generated and used to compute a hash if a HashRequest does not specify a salt.


Copyright © 2004-2012 The Apache Software Foundation. All Rights Reserved.