Coverage Report - org.acegisecurity.providers.encoding.MessageDigestPasswordEncoder
 
Classes in this File Line Coverage Branch Coverage Complexity
MessageDigestPasswordEncoder
100% 
100% 
1.833
 
 1  
 package org.acegisecurity.providers.encoding;
 2  
 
 3  
 import org.apache.commons.codec.binary.Base64;
 4  
 import org.apache.commons.codec.binary.Hex;
 5  
 
 6  
 import java.security.MessageDigest;
 7  
 import java.security.NoSuchAlgorithmException;
 8  
 
 9  
 /**
 10  
  * Base for digest password encoders.
 11  
  * <p>This class can be used stand-alone, or one of the subclasses can be used for compatiblity and convenience.
 12  
  * When using this class directly you must specify a
 13  
  * <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/CryptoSpec.html#AppA">
 14  
  * Message Digest Algorithm</a> to use as a constructor arg</p>
 15  
  *
 16  
  * <p>The encoded password hash is normally returned as Hex (32 char) version of the hash bytes.
 17  
  * Setting the <tt>encodeHashAsBase64</tt> property to <tt>true</tt> will cause the encoded pass to be returned
 18  
  * as Base64 text, which will consume 24 characters.
 19  
  * See {@link BaseDigestPasswordEncoder#setEncodeHashAsBase64(boolean)}
 20  
  * </p>
 21  
  * <p>
 22  
  * This PasswordEncoder can be used directly as in the following example:<br/>
 23  
  * <pre>
 24  
  * &lt;bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.MessageDigestPasswordEncoder"&gt;
 25  
  *     &lt;constructor-arg value="MD5"/&gt;
 26  
  * &lt;/bean&gt;
 27  
  * </pre>
 28  
  * </p>
 29  
  *
 30  
  * @author Ray Krueger
 31  
  * @since 1.0.1
 32  
  */
 33  
 public class MessageDigestPasswordEncoder extends BaseDigestPasswordEncoder {
 34  
 
 35  
     private final String algorithm;
 36  
 
 37  
     /**
 38  
      * The digest algorithm to use
 39  
      * Supports the named <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/CryptoSpec.html#AppA">
 40  
      * Message Digest Algorithms</a> in the Java environment.
 41  
      *
 42  
      * @param algorithm
 43  
      */
 44  
     public MessageDigestPasswordEncoder(String algorithm) {
 45  7
         this(algorithm, false);
 46  6
     }
 47  
 
 48  
     /**
 49  
      * Convenience constructor for specifying the algorithm and whether or not to enable base64 encoding
 50  
      *
 51  
      * @param algorithm
 52  
      * @param encodeHashAsBase64
 53  
      * @throws IllegalArgumentException if an unknown
 54  
      */
 55  7
     public MessageDigestPasswordEncoder(String algorithm, boolean encodeHashAsBase64) throws IllegalArgumentException {
 56  7
         this.algorithm = algorithm;
 57  7
         setEncodeHashAsBase64(encodeHashAsBase64);
 58  
         //Validity Check
 59  7
         getMessageDigest();
 60  6
     }
 61  
 
 62  
     /**
 63  
      * Encodes the rawPass using a MessageDigest.
 64  
      * If a salt is specified it will be merged with the password before encoding.
 65  
      *
 66  
      * @param rawPass The plain text password
 67  
      * @param salt The salt to sprinkle
 68  
      * @return Hex string of password digest (or base64 encoded string if encodeHashAsBase64 is enabled.
 69  
      */
 70  
     public String encodePassword(String rawPass, Object salt) {
 71  14
         String saltedPass = mergePasswordAndSalt(rawPass, salt, false);
 72  
 
 73  14
         MessageDigest messageDigest = getMessageDigest();
 74  
 
 75  14
         byte[] digest = messageDigest.digest(saltedPass.getBytes());
 76  
 
 77  14
         if (getEncodeHashAsBase64()) {
 78  6
             return new String(Base64.encodeBase64(digest));
 79  
         } else {
 80  8
             return new String(Hex.encodeHex(digest));
 81  
         }
 82  
     }
 83  
 
 84  
     /**
 85  
      * Get a MessageDigest instance for the given algorithm.
 86  
      * Throws an IllegalArgumentException if <i>algorithm</i> is unknown
 87  
      *
 88  
      * @return MessageDigest instance
 89  
      * @throws IllegalArgumentException if NoSuchAlgorithmException is thrown
 90  
      */
 91  
     protected final MessageDigest getMessageDigest() throws IllegalArgumentException {
 92  
         try {
 93  21
             return MessageDigest.getInstance(algorithm);
 94  1
         } catch (NoSuchAlgorithmException e) {
 95  1
             throw new IllegalArgumentException("No such algorithm [" + algorithm + "]");
 96  
         }
 97  
     }
 98  
 
 99  
     /**
 100  
      * Takes a previously encoded password and compares it with a rawpassword after mixing in the salt and
 101  
      * encoding that value
 102  
      *
 103  
      * @param encPass previously encoded password
 104  
      * @param rawPass plain text password
 105  
      * @param salt salt to mix into password
 106  
      * @return true or false
 107  
      */
 108  
     public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
 109  8
         String pass1 = "" + encPass;
 110  8
         String pass2 = encodePassword(rawPass, salt);
 111  
 
 112  8
         return pass1.equals(pass2);
 113  
     }
 114  
 
 115  
     public String getAlgorithm() {
 116  1
         return algorithm;
 117  
     }
 118  
 }