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