package com.zt.core.security; 
 | 
  
 | 
import org.apache.commons.logging.Log; 
 | 
import org.apache.commons.logging.LogFactory; 
 | 
  
 | 
import java.security.SecureRandom; 
 | 
import java.util.regex.Pattern; 
 | 
  
 | 
/** 
 | 
 * Implementation of PasswordEncoder that uses the BCrypt strong hashing function. Clients 
 | 
 * can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a SecureRandom 
 | 
 * instance. The larger the strength parameter the more work will have to be done 
 | 
 * (exponentially) to hash the passwords. The default value is 10. 
 | 
 * 
 | 
 * @author Dave Syer 
 | 
 * 
 | 
 */ 
 | 
public class BCryptPasswordEncoder implements PasswordEncoder { 
 | 
    private Pattern BCRYPT_PATTERN = Pattern 
 | 
            .compile("\\A\\$2a?\\$\\d\\d\\$[./0-9A-Za-z]{53}"); 
 | 
    private final Log logger = LogFactory.getLog(getClass()); 
 | 
  
 | 
    private final int strength; 
 | 
  
 | 
    private final SecureRandom random; 
 | 
  
 | 
    public BCryptPasswordEncoder() { 
 | 
        this(-1); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param strength the log rounds to use, between 4 and 31 
 | 
     */ 
 | 
    public BCryptPasswordEncoder(int strength) { 
 | 
        this(strength, null); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param strength the log rounds to use, between 4 and 31 
 | 
     * @param random the secure random instance to use 
 | 
     * 
 | 
     */ 
 | 
    public BCryptPasswordEncoder(int strength, SecureRandom random) { 
 | 
        if (strength != -1 && (strength < BCrypt.MIN_LOG_ROUNDS || strength > BCrypt.MAX_LOG_ROUNDS)) { 
 | 
            throw new IllegalArgumentException("Bad strength"); 
 | 
        } 
 | 
        this.strength = strength; 
 | 
        this.random = random; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public String encode(CharSequence rawPassword) { 
 | 
        String salt; 
 | 
        if (strength > 0) { 
 | 
            if (random != null) { 
 | 
                salt = BCrypt.gensalt(strength, random); 
 | 
            } 
 | 
            else { 
 | 
                salt = BCrypt.gensalt(strength); 
 | 
            } 
 | 
        } 
 | 
        else { 
 | 
            salt = BCrypt.gensalt(); 
 | 
        } 
 | 
        return BCrypt.hashpw(rawPassword.toString(), salt); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public boolean matches(CharSequence rawPassword, String encodedPassword) { 
 | 
        if (encodedPassword == null || encodedPassword.length() == 0) { 
 | 
            logger.warn("Empty encoded password"); 
 | 
            return false; 
 | 
        } 
 | 
  
 | 
        if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) { 
 | 
            logger.warn("Encoded password does not look like BCrypt"); 
 | 
            return false; 
 | 
        } 
 | 
  
 | 
        return BCrypt.checkpw(rawPassword.toString(), encodedPassword); 
 | 
    } 
 | 
} 
 |