1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.util;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.util.Base64;
20  import com.liferay.portal.kernel.util.Digester;
21  import com.liferay.portal.kernel.util.DigesterUtil;
22  import com.liferay.portal.kernel.util.GetterUtil;
23  import com.liferay.portal.kernel.util.ServerDetector;
24  import com.liferay.portal.kernel.util.StringPool;
25  
26  import java.security.Key;
27  import java.security.Provider;
28  import java.security.SecureRandom;
29  import java.security.Security;
30  
31  import java.util.Map;
32  import java.util.concurrent.ConcurrentHashMap;
33  
34  import javax.crypto.Cipher;
35  import javax.crypto.KeyGenerator;
36  
37  /**
38   * <a href="Encryptor.java.html"><b><i>View Source</i></b></a>
39   *
40   * @author Brian Wing Shun Chan
41   * @author Shuyang Zhou
42   */
43  public class Encryptor {
44  
45      public static final String ENCODING = Digester.ENCODING;
46  
47      public static final String KEY_ALGORITHM = "DES";
48  
49      public static final String SUN_PROVIDER_CLASS =
50          "com.sun.crypto.provider.SunJCE";
51  
52      public static final String IBM_PROVIDER_CLASS =
53          "com.ibm.crypto.provider.IBMJCE";
54  
55      public static final String PROVIDER_CLASS = GetterUtil.getString(
56          SystemProperties.get(Encryptor.class.getName() + ".provider.class"),
57          SUN_PROVIDER_CLASS);
58  
59      public static Key generateKey() throws EncryptorException {
60          return generateKey(KEY_ALGORITHM);
61      }
62  
63      public static Key generateKey(String algorithm) throws EncryptorException {
64          try {
65              Security.addProvider(getProvider());
66  
67              KeyGenerator generator = KeyGenerator.getInstance(algorithm);
68              generator.init(56, new SecureRandom());
69  
70              Key key = generator.generateKey();
71  
72              return key;
73          }
74          catch (Exception e) {
75              throw new EncryptorException(e);
76          }
77      }
78  
79      public static Provider getProvider()
80          throws ClassNotFoundException, IllegalAccessException,
81                 InstantiationException {
82  
83          Class<?> providerClass = null;
84  
85          try {
86              providerClass = Class.forName(PROVIDER_CLASS);
87          }
88          catch (ClassNotFoundException cnfe) {
89              if ((ServerDetector.isWebSphere()) &&
90                  (PROVIDER_CLASS.equals(SUN_PROVIDER_CLASS))) {
91  
92                  if (_log.isWarnEnabled()) {
93                      _log.warn(
94                          "WebSphere does not have " + SUN_PROVIDER_CLASS +
95                              ", using " + IBM_PROVIDER_CLASS + " instead");
96                  }
97  
98                  providerClass = Class.forName(IBM_PROVIDER_CLASS);
99              }
100             else if (System.getProperty("java.vm.vendor").equals(
101                         "IBM Corporation")) {
102 
103                 if (_log.isWarnEnabled()) {
104                     _log.warn(
105                         "IBM JVM does not have " + SUN_PROVIDER_CLASS +
106                             ", using " + IBM_PROVIDER_CLASS + " instead");
107                 }
108 
109                 providerClass = Class.forName(IBM_PROVIDER_CLASS);
110             }
111             else {
112                 throw cnfe;
113             }
114         }
115 
116         return (Provider)providerClass.newInstance();
117     }
118 
119     public static String decrypt(Key key, String encryptedString)
120         throws EncryptorException {
121 
122         byte[] encryptedBytes = Base64.decode(encryptedString);
123 
124         return decryptUnencodedAsString(key, encryptedBytes);
125     }
126 
127     public static byte[] decryptUnencodedAsBytes(Key key, byte[] encryptedBytes)
128         throws EncryptorException {
129 
130         String algorithm = key.getAlgorithm();
131 
132         String cacheKey = algorithm.concat(StringPool.POUND).concat(
133             key.toString());
134 
135         Cipher cipher = _decryptCipherMap.get(cacheKey);
136 
137         try {
138             if (cipher == null) {
139                 Security.addProvider(getProvider());
140 
141                 cipher = Cipher.getInstance(algorithm);
142 
143                 cipher.init(Cipher.DECRYPT_MODE, key);
144 
145                 _decryptCipherMap.put(cacheKey, cipher);
146             }
147 
148             synchronized (cipher) {
149                 return cipher.doFinal(encryptedBytes);
150             }
151         }
152         catch (Exception e) {
153             throw new EncryptorException(e);
154         }
155     }
156 
157     public static String decryptUnencodedAsString(
158             Key key, byte[] encryptedBytes)
159         throws EncryptorException {
160 
161         try {
162             byte[] decryptedBytes = decryptUnencodedAsBytes(
163                 key, encryptedBytes);
164 
165             return new String(decryptedBytes, ENCODING);
166         }
167         catch (Exception e) {
168             throw new EncryptorException(e);
169         }
170     }
171 
172     public static String digest(String text) {
173         return DigesterUtil.digest(text);
174     }
175 
176     public static String digest(String algorithm, String text) {
177         return DigesterUtil.digest(algorithm, text);
178     }
179 
180     public static String encrypt(Key key, String plainText)
181         throws EncryptorException {
182 
183         byte[] encryptedBytes = encryptUnencoded(key, plainText);
184 
185         return Base64.encode(encryptedBytes);
186     }
187 
188     public static byte[] encryptUnencoded(Key key, byte[] plainBytes)
189         throws EncryptorException {
190 
191         String algorithm = key.getAlgorithm();
192 
193         String cacheKey = algorithm.concat(StringPool.POUND).concat(
194             key.toString());
195 
196         Cipher cipher = _encryptCipherMap.get(cacheKey);
197 
198         try {
199             if (cipher == null) {
200                 Security.addProvider(getProvider());
201 
202                 cipher = Cipher.getInstance(algorithm);
203 
204                 cipher.init(Cipher.ENCRYPT_MODE, key);
205 
206                 _encryptCipherMap.put(cacheKey, cipher);
207             }
208 
209             synchronized (cipher) {
210                 return cipher.doFinal(plainBytes);
211             }
212         }
213         catch (Exception e) {
214             throw new EncryptorException(e);
215         }
216     }
217 
218     public static byte[] encryptUnencoded(Key key, String plainText)
219         throws EncryptorException {
220 
221         try {
222             byte[] decryptedBytes = plainText.getBytes(ENCODING);
223 
224             return encryptUnencoded(key, decryptedBytes);
225         }
226         catch (Exception e) {
227             throw new EncryptorException(e);
228         }
229     }
230 
231     private static Log _log = LogFactoryUtil.getLog(Encryptor.class);
232 
233     private static Map<String, Cipher> _decryptCipherMap =
234         new ConcurrentHashMap<String, Cipher>(1, 1f, 1);
235     private static Map<String, Cipher> _encryptCipherMap =
236         new ConcurrentHashMap<String, Cipher>(1, 1f, 1);
237 
238 }