001
014
015 package com.liferay.util;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.util.Base64;
020 import com.liferay.portal.kernel.util.Digester;
021 import com.liferay.portal.kernel.util.DigesterUtil;
022 import com.liferay.portal.kernel.util.GetterUtil;
023 import com.liferay.portal.kernel.util.PropsKeys;
024 import com.liferay.portal.kernel.util.PropsUtil;
025 import com.liferay.portal.kernel.util.ServerDetector;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.kernel.util.SystemProperties;
028
029 import java.security.Key;
030 import java.security.Provider;
031 import java.security.SecureRandom;
032 import java.security.Security;
033
034 import java.util.Map;
035 import java.util.concurrent.ConcurrentHashMap;
036
037 import javax.crypto.Cipher;
038 import javax.crypto.KeyGenerator;
039
040
044 public class Encryptor {
045
046 public static final String ENCODING = Digester.ENCODING;
047
048 public static final String KEY_ALGORITHM = GetterUtil.getString(
049 PropsUtil.get(PropsKeys.COMPANY_ENCRYPTION_ALGORITHM)).toUpperCase();
050
051 public static final int KEY_SIZE = GetterUtil.getInteger(
052 PropsUtil.get(PropsKeys.COMPANY_ENCRYPTION_KEY_SIZE));
053
054 public static final String SUN_PROVIDER_CLASS =
055 "com.sun.crypto.provider.SunJCE";
056
057 public static final String IBM_PROVIDER_CLASS =
058 "com.ibm.crypto.provider.IBMJCE";
059
060 public static final String PROVIDER_CLASS = GetterUtil.getString(
061 SystemProperties.get(Encryptor.class.getName() + ".provider.class"),
062 SUN_PROVIDER_CLASS);
063
064 public static Key generateKey() throws EncryptorException {
065 return generateKey(KEY_ALGORITHM);
066 }
067
068 public static Key generateKey(String algorithm) throws EncryptorException {
069 try {
070 Security.addProvider(getProvider());
071
072 KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
073
074 keyGenerator.init(KEY_SIZE, new SecureRandom());
075
076 Key key = keyGenerator.generateKey();
077
078 return key;
079 }
080 catch (Exception e) {
081 throw new EncryptorException(e);
082 }
083 }
084
085 public static Provider getProvider()
086 throws ClassNotFoundException, IllegalAccessException,
087 InstantiationException {
088
089 Class<?> providerClass = null;
090
091 try {
092 providerClass = Class.forName(PROVIDER_CLASS);
093 }
094 catch (ClassNotFoundException cnfe) {
095 if ((ServerDetector.isWebSphere()) &&
096 (PROVIDER_CLASS.equals(SUN_PROVIDER_CLASS))) {
097
098 if (_log.isWarnEnabled()) {
099 _log.warn(
100 "WebSphere does not have " + SUN_PROVIDER_CLASS +
101 ", using " + IBM_PROVIDER_CLASS + " instead");
102 }
103
104 providerClass = Class.forName(IBM_PROVIDER_CLASS);
105 }
106 else if (System.getProperty("java.vm.vendor").equals(
107 "IBM Corporation")) {
108
109 if (_log.isWarnEnabled()) {
110 _log.warn(
111 "IBM JVM does not have " + SUN_PROVIDER_CLASS +
112 ", using " + IBM_PROVIDER_CLASS + " instead");
113 }
114
115 providerClass = Class.forName(IBM_PROVIDER_CLASS);
116 }
117 else {
118 throw cnfe;
119 }
120 }
121
122 return (Provider)providerClass.newInstance();
123 }
124
125 public static String decrypt(Key key, String encryptedString)
126 throws EncryptorException {
127
128 byte[] encryptedBytes = Base64.decode(encryptedString);
129
130 return decryptUnencodedAsString(key, encryptedBytes);
131 }
132
133 public static byte[] decryptUnencodedAsBytes(Key key, byte[] encryptedBytes)
134 throws EncryptorException {
135
136 String algorithm = key.getAlgorithm();
137
138 String cacheKey = algorithm.concat(StringPool.POUND).concat(
139 key.toString());
140
141 Cipher cipher = _decryptCipherMap.get(cacheKey);
142
143 try {
144 if (cipher == null) {
145 Security.addProvider(getProvider());
146
147 cipher = Cipher.getInstance(algorithm);
148
149 cipher.init(Cipher.DECRYPT_MODE, key);
150
151 _decryptCipherMap.put(cacheKey, cipher);
152 }
153
154 synchronized (cipher) {
155 return cipher.doFinal(encryptedBytes);
156 }
157 }
158 catch (Exception e) {
159 throw new EncryptorException(e);
160 }
161 }
162
163 public static String decryptUnencodedAsString(
164 Key key, byte[] encryptedBytes)
165 throws EncryptorException {
166
167 try {
168 byte[] decryptedBytes = decryptUnencodedAsBytes(
169 key, encryptedBytes);
170
171 return new String(decryptedBytes, ENCODING);
172 }
173 catch (Exception e) {
174 throw new EncryptorException(e);
175 }
176 }
177
178 public static String digest(String text) {
179 return DigesterUtil.digest(text);
180 }
181
182 public static String digest(String algorithm, String text) {
183 return DigesterUtil.digest(algorithm, text);
184 }
185
186 public static String encrypt(Key key, String plainText)
187 throws EncryptorException {
188
189 byte[] encryptedBytes = encryptUnencoded(key, plainText);
190
191 return Base64.encode(encryptedBytes);
192 }
193
194 public static byte[] encryptUnencoded(Key key, byte[] plainBytes)
195 throws EncryptorException {
196
197 String algorithm = key.getAlgorithm();
198
199 String cacheKey = algorithm.concat(StringPool.POUND).concat(
200 key.toString());
201
202 Cipher cipher = _encryptCipherMap.get(cacheKey);
203
204 try {
205 if (cipher == null) {
206 Security.addProvider(getProvider());
207
208 cipher = Cipher.getInstance(algorithm);
209
210 cipher.init(Cipher.ENCRYPT_MODE, key);
211
212 _encryptCipherMap.put(cacheKey, cipher);
213 }
214
215 synchronized (cipher) {
216 return cipher.doFinal(plainBytes);
217 }
218 }
219 catch (Exception e) {
220 throw new EncryptorException(e);
221 }
222 }
223
224 public static byte[] encryptUnencoded(Key key, String plainText)
225 throws EncryptorException {
226
227 try {
228 byte[] decryptedBytes = plainText.getBytes(ENCODING);
229
230 return encryptUnencoded(key, decryptedBytes);
231 }
232 catch (Exception e) {
233 throw new EncryptorException(e);
234 }
235 }
236
237 private static Log _log = LogFactoryUtil.getLog(Encryptor.class);
238
239 private static Map<String, Cipher> _decryptCipherMap =
240 new ConcurrentHashMap<String, Cipher>(1, 1f, 1);
241 private static Map<String, Cipher> _encryptCipherMap =
242 new ConcurrentHashMap<String, Cipher>(1, 1f, 1);
243
244 }