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