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