View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.security;
8   
9   import org.mule.api.lifecycle.InitialisationException;
10  import org.mule.api.security.CryptoFailureException;
11  import org.mule.config.i18n.CoreMessages;
12  import org.mule.util.Base64;
13  
14  import java.io.ByteArrayInputStream;
15  import java.io.IOException;
16  import java.io.InputStream;
17  import java.security.GeneralSecurityException;
18  import java.security.spec.AlgorithmParameterSpec;
19  import java.security.spec.KeySpec;
20  
21  import javax.crypto.Cipher;
22  import javax.crypto.SecretKey;
23  
24  import org.apache.commons.io.IOUtils;
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  /**
29   * A JCE based encryption strategy. It also provides base64 encoding of
30   * encrypted/decrypted data by setting the base64encoding attribute.
31   */
32  public abstract class AbstractJCEEncryptionStrategy extends AbstractNamedEncryptionStrategy
33  {
34      /**
35       * logger used by this class
36       */
37      protected transient Log logger = LogFactory.getLog(getClass());
38  
39      protected KeySpec keySpec;
40      protected SecretKey secretKey;
41      protected Cipher encryptCipher;
42      protected Cipher decryptCipher;
43  
44      protected String algorithm = null;
45  
46      protected boolean base64Encoding = true;
47  
48      public void initialise() throws InitialisationException
49      {
50          if (algorithm == null)
51          {
52              throw new InitialisationException(CoreMessages.objectIsNull("Algorithm"), this);
53          }
54          else
55          {
56              logger.debug("Using encryption algorithm: " + algorithm);
57          }
58  
59          keySpec = createKeySpec();
60  
61          try
62          {
63              secretKey = getSecretKey();
64              // Create Ciphers
65              encryptCipher = Cipher.getInstance(getAlgorithm());
66              decryptCipher = Cipher.getInstance(getAlgorithm());
67  
68              AlgorithmParameterSpec paramSpec = createAlgorithmParameterSpec();
69              if (paramSpec != null)
70              {
71                  encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
72                  decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);
73              }
74              else
75              {
76                  encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
77                  decryptCipher.init(Cipher.DECRYPT_MODE, secretKey);
78              }
79  
80          }
81          catch (Exception e)
82          {
83              throw new InitialisationException(CoreMessages.failedToCreate("encryption ciphers"),
84                  e, this);
85          }
86      }
87  
88      protected abstract SecretKey getSecretKey() throws GeneralSecurityException;
89  
90      public InputStream encrypt(InputStream data, Object info) throws CryptoFailureException {
91          try
92          {
93              return new ByteArrayInputStream(this.encrypt(IOUtils.toByteArray(data), info));
94          }
95          catch (IOException e)
96          {
97              throw new CryptoFailureException(this, e);
98          }
99      }
100 
101     public InputStream decrypt(InputStream data, Object info) throws CryptoFailureException {
102         try
103         {
104             return new ByteArrayInputStream(this.decrypt(IOUtils.toByteArray(data), info));
105         }
106         catch (IOException e)
107         {
108             throw new CryptoFailureException(this, e);
109         }
110     }
111     
112     public byte[] encrypt(byte[] data, Object info) throws CryptoFailureException
113     {
114         try
115         {
116             byte[] buf = encryptCipher.doFinal(data);
117             if (base64Encoding)
118             {
119                 return Base64.encodeBytes(buf).getBytes();
120             }
121             else
122             {
123                 return buf;
124             }
125         }
126         catch (Exception e)
127         {
128             throw new CryptoFailureException(this, e);
129         }
130     }
131 
132     public byte[] decrypt(byte[] data, Object info) throws CryptoFailureException
133     {
134         try
135         {
136             byte[] dec = data;
137             if (base64Encoding)
138             {
139                 dec = Base64.decode(new String(data));
140             }
141             return decryptCipher.doFinal(dec);
142         }
143         catch (Exception e)
144         {
145             throw new CryptoFailureException(this, e);
146         }
147     }
148 
149     public String getAlgorithm()
150     {
151         return algorithm;
152     }
153 
154     public void setAlgorithm(String algorithm)
155     {
156         this.algorithm = algorithm;
157     }
158 
159     public String toString()
160     {
161         StringBuffer buf = new StringBuffer();
162         buf.append("Algorithm=").append(algorithm);
163         return buf.toString();
164     }
165 
166     public boolean isBase64Encoding()
167     {
168         return base64Encoding;
169     }
170 
171     public void setBase64Encoding(boolean base64Encoding)
172     {
173         this.base64Encoding = base64Encoding;
174     }
175 
176     protected abstract KeySpec createKeySpec();
177 
178     protected abstract AlgorithmParameterSpec createAlgorithmParameterSpec();
179 
180 }