Coverage Report - org.acegisecurity.util.EncryptionUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
EncryptionUtils
69% 
100% 
1.636
 
 1  
 /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
 2  
  *
 3  
  * Licensed under the Apache License, Version 2.0 (the "License");
 4  
  * you may not use this file except in compliance with the License.
 5  
  * You may obtain a copy of the License at
 6  
  *
 7  
  *     http://www.apache.org/licenses/LICENSE-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing, software
 10  
  * distributed under the License is distributed on an "AS IS" BASIS,
 11  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
  * See the License for the specific language governing permissions and
 13  
  * limitations under the License.
 14  
  */
 15  
 
 16  
 package org.acegisecurity.util;
 17  
 
 18  
 import java.io.UnsupportedEncodingException;
 19  
 import java.security.spec.KeySpec;
 20  
 
 21  
 import javax.crypto.Cipher;
 22  
 import javax.crypto.SecretKey;
 23  
 import javax.crypto.SecretKeyFactory;
 24  
 import javax.crypto.spec.DESedeKeySpec;
 25  
 
 26  
 import org.acegisecurity.AcegiSecurityException;
 27  
 import org.apache.commons.codec.binary.Base64;
 28  
 import org.springframework.util.Assert;
 29  
 
 30  
 /**
 31  
  * A static utility class that can encrypt and decrypt text.
 32  
  *
 33  
  * <p>This class is useful if you have simple needs and wish to use the DESede
 34  
  * encryption cipher. More sophisticated requirements will need to use the
 35  
  * Java crypto libraries directly.
 36  
  *
 37  
  * @author Alan Stewart
 38  
  * @author Ben Alex
 39  
  * @version $Id: EncryptionUtils.java 1784 2007-02-24 21:00:24Z luke_t $
 40  
  */
 41  
 public final class EncryptionUtils {
 42  
 
 43  
     /**
 44  
      * This is a static class that should not be instantiated.
 45  
      */
 46  0
     private EncryptionUtils() {}
 47  
 
 48  
     /**
 49  
      * Converts a String into a byte array using UTF-8, falling back to the
 50  
      * platform's default character set if UTF-8 fails.
 51  
      *
 52  
      * @param input the input (required)
 53  
      * @return a byte array representation of the input string
 54  
      */
 55  
     public static byte[] stringToByteArray(String input) {
 56  17
         Assert.hasLength(input, "Input required");
 57  
         try {
 58  14
             return input.getBytes("UTF-8");
 59  0
         } catch (UnsupportedEncodingException fallbackToDefault) {
 60  0
             return input.getBytes();
 61  
         }
 62  
     }
 63  
 
 64  
     /**
 65  
      * Converts a byte array into a String using UTF-8, falling back to the
 66  
      * platform's default character set if UTF-8 fails.
 67  
      *
 68  
      * @param byteArray the byte array to convert (required)
 69  
      * @return a string representation of the byte array
 70  
      */
 71  
     public static String byteArrayToString(byte[] byteArray) {
 72  7
         Assert.notNull(byteArray, "ByteArray required");
 73  7
         Assert.isTrue(byteArray.length > 0, "ByteArray cannot be empty");
 74  
         try {
 75  7
             return new String(byteArray, "UTF8");
 76  0
         } catch (final UnsupportedEncodingException e) {
 77  0
             return new String(byteArray);
 78  
         }
 79  
     }
 80  
 
 81  
     private static byte[] cipher(String key, byte[] passedBytes, int cipherMode) throws EncryptionException {
 82  
         try {
 83  7
             final KeySpec keySpec = new DESedeKeySpec(stringToByteArray(key));
 84  7
             final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
 85  7
             final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
 86  7
             final SecretKey secretKey = keyFactory.generateSecret(keySpec);
 87  7
             cipher.init(cipherMode, secretKey);
 88  7
             return cipher.doFinal(passedBytes);
 89  0
         } catch (final Exception e) {
 90  0
             throw new EncryptionException(e.getMessage(), e);
 91  
         }
 92  
     }
 93  
 
 94  
     /**
 95  
      * Encrypts the inputString using the key.
 96  
      *
 97  
      * @param key at least 24 character long key (required)
 98  
      * @param inputString the string to encrypt (required)
 99  
      * @return the encrypted version of the inputString
 100  
      * @throws EncryptionException in the event of an encryption failure
 101  
      */
 102  
     public static String encrypt(String key, String inputString) throws EncryptionException {
 103  7
         isValidKey(key);
 104  5
         final byte[] cipherText = cipher(key, stringToByteArray(inputString), Cipher.ENCRYPT_MODE);
 105  3
         return byteArrayToString(Base64.encodeBase64(cipherText));
 106  
     }
 107  
 
 108  
     /**
 109  
      * Encrypts the inputBytes using the key.
 110  
      *
 111  
      * @param key at least 24 character long key (required)
 112  
      * @param inputBytes the bytes to encrypt (required)
 113  
      * @return the encrypted version of the inputBytes
 114  
      * @throws EncryptionException in the event of an encryption failure
 115  
      */
 116  
     public static byte[] encrypt(String key, byte[] inputBytes) throws EncryptionException {
 117  1
         isValidKey(key);
 118  1
         return Base64.encodeBase64(cipher(key, inputBytes, Cipher.ENCRYPT_MODE));
 119  
     }
 120  
 
 121  
     /**
 122  
      * Decrypts the inputString using the key.
 123  
      *
 124  
      * @param key the key used to originally encrypt the string (required)
 125  
      * @param inputString the encrypted string (required)
 126  
      * @return the decrypted version of inputString
 127  
      * @throws EncryptionException in the event of an encryption failure
 128  
      */
 129  
     public static String decrypt(String key, String inputString) throws EncryptionException {
 130  3
         Assert.hasText(key, "A key is required to attempt decryption");
 131  3
         final byte[] cipherText = cipher(key, Base64.decodeBase64(stringToByteArray(inputString)), Cipher.DECRYPT_MODE);
 132  2
         return byteArrayToString(cipherText);
 133  
     }
 134  
 
 135  
     /**
 136  
      * Decrypts the inputBytes using the key.
 137  
      *
 138  
      * @param key the key used to originally encrypt the string (required)
 139  
      * @param inputBytes the encrypted bytes (required)
 140  
      * @return the decrypted version of inputBytes
 141  
      * @throws EncryptionException in the event of an encryption failure
 142  
      */
 143  
     public static byte[] decrypt(String key, byte[] inputBytes) throws EncryptionException {
 144  1
         Assert.hasText(key, "A key is required to attempt decryption");
 145  1
         return cipher(key, Base64.decodeBase64(inputBytes), Cipher.DECRYPT_MODE);
 146  
     }
 147  
 
 148  
     private static void isValidKey(String key) {
 149  8
         Assert.hasText(key, "A key to perform the encryption is required");
 150  6
         Assert.isTrue(key.length() >= 24, "Key must be at least 24 characters long");
 151  6
     }
 152  
 
 153  
     public static class EncryptionException extends AcegiSecurityException {
 154  
         private static final long serialVersionUID = 1L;
 155  
 
 156  
         public EncryptionException(String message, Throwable t) {
 157  0
             super(message, t);
 158  0
         }
 159  
 
 160  
         public EncryptionException(String message) {
 161  0
             super(message);
 162  0
         }
 163  
     }
 164  
 }