package net.unicon.cas.addons.authentication.handler; import net.unicon.cas.addons.support.ThreadSafe; import org.apache.shiro.crypto.hash.ConfigurableHashService; import org.apache.shiro.crypto.hash.DefaultHashService; import org.apache.shiro.crypto.hash.HashRequest; import org.jasig.cas.authentication.handler.PasswordEncoder; /** * Password encoder with salted and more cryptographically stronger hashing support which delegates all the work * to Apache Shiro HashService API. * <p/> * This encoder optionally supports configuration options for <b>digestAlgorithmName</b> , <b>salt</b>, <b>hashIterations</b> * <p/> * If these options are not set at configuration time, the defaults as defined in <code>DefaultHashService</code> are used. * * @author Dmitriy Kopylenko * @author Unicon, inc. * @see <a href="DefaultHashService">http://shiro.apache.org/static/current/apidocs/org/apache/shiro/crypto/hash/DefaultHashService.html</a> * @since 1.0.2 */ @ThreadSafe public final class ShiroHashServicePasswordEncoder implements PasswordEncoder { private final ConfigurableHashService hashService = new DefaultHashService(); private String digestAlgorithmName; private String salt; private int hashIterations; /** * @param digestAlgorithmName one of: * <ul> * <li>MD2</li> * <li>MD5</li> * <li>SHA-1</li> * <li>SHA-256</li> * <li>SHA-384</li> * <li>SHA-512</li> * </ul> */ public void setDigestAlgorithmName(String digestAlgorithmName) { this.digestAlgorithmName = digestAlgorithmName; } public void setSalt(String salt) { this.salt = salt; } public void setHashIterations(int hashIterations) { this.hashIterations = hashIterations; } @Override public String encode(String password) { if (password == null) { return null; } return this.hashService.computeHash(new HashRequest.Builder().setSalt(this.salt).setSource(password).build()).toHex(); } /** * This method is only intended to be called by the infrastructure code managing instances of this class * once during initialization of this instance */ void init() throws Throwable { if (this.digestAlgorithmName != null) { this.hashService.setHashAlgorithmName(this.digestAlgorithmName); } if (this.hashIterations > 0) { this.hashService.setHashIterations(this.hashIterations); } } }