1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.core.impl.encryption;
17
18 import org.apache.commons.codec.binary.Base64;
19 import org.apache.commons.lang.StringUtils;
20 import org.kuali.rice.core.api.config.property.ConfigContext;
21 import org.kuali.rice.core.api.encryption.EncryptionService;
22
23 import javax.crypto.Cipher;
24 import javax.crypto.KeyGenerator;
25 import javax.crypto.SecretKey;
26 import javax.crypto.SecretKeyFactory;
27 import javax.crypto.spec.DESKeySpec;
28 import java.io.UnsupportedEncodingException;
29 import java.security.GeneralSecurityException;
30 import java.security.MessageDigest;
31
32
33
34
35
36
37 public class DemonstrationGradeEncryptionServiceImpl implements EncryptionService {
38 public final static String ALGORITHM = "DES/ECB/PKCS5Padding";
39 public final static String HASH_ALGORITHM = "SHA";
40
41 private final static String CHARSET = "UTF-8";
42
43 private transient SecretKey desKey;
44
45 private boolean isEnabled = false;
46
47 public DemonstrationGradeEncryptionServiceImpl() throws Exception {
48 if (desKey != null) {
49 throw new RuntimeException("The secret key must be kept secret. Storing it in the Java source code is a really bad idea.");
50 }
51 String key = ConfigContext.getCurrentContextConfig().getProperty("encryption.key");
52 if (!StringUtils.isEmpty(key)) {
53 setSecretKey(key);
54 }
55 }
56
57 public boolean isEnabled() {
58 return isEnabled;
59 }
60
61 public String encrypt(Object valueToHide) throws GeneralSecurityException {
62 checkEnabled();
63
64 if (valueToHide == null) {
65 return "";
66 }
67
68
69 Cipher cipher = Cipher.getInstance(ALGORITHM);
70 cipher.init(Cipher.ENCRYPT_MODE, desKey);
71
72 try {
73
74 byte[] cleartext = valueToHide.toString().getBytes(CHARSET);
75
76
77 byte[] ciphertext = cipher.doFinal(cleartext);
78
79 return new String(Base64.encodeBase64(ciphertext), CHARSET);
80 } catch (Exception e) {
81 throw new RuntimeException(e);
82 }
83
84 }
85
86 public String decrypt(String ciphertext) throws GeneralSecurityException {
87 checkEnabled();
88
89 if (StringUtils.isBlank(ciphertext)) {
90 return "";
91 }
92
93
94 Cipher cipher = Cipher.getInstance(ALGORITHM);
95 cipher.init(Cipher.DECRYPT_MODE, desKey);
96
97 try {
98
99 byte[] encryptedData = Base64.decodeBase64(ciphertext.getBytes(CHARSET));
100
101
102 byte[] cleartext1 = cipher.doFinal(encryptedData);
103 return new String(cleartext1, CHARSET);
104 } catch (UnsupportedEncodingException e) {
105 throw new RuntimeException(e);
106 }
107 }
108
109 public byte[] encryptBytes(byte[] valueToHide) throws GeneralSecurityException {
110 checkEnabled();
111
112 if (valueToHide == null) {
113 return new byte[0];
114 }
115
116
117 Cipher cipher = Cipher.getInstance(ALGORITHM);
118 cipher.init(Cipher.ENCRYPT_MODE, desKey);
119
120
121 byte[] cleartext = valueToHide;
122
123
124 byte[] ciphertext = cipher.doFinal(cleartext);
125
126 return ciphertext;
127 }
128
129 public byte[] decryptBytes(byte[] ciphertext) throws GeneralSecurityException {
130 checkEnabled();
131
132 if (ciphertext == null) {
133 return new byte[0];
134 }
135
136
137 Cipher cipher = Cipher.getInstance(ALGORITHM);
138 cipher.init(Cipher.DECRYPT_MODE, desKey);
139
140
141 byte[] encryptedData = ciphertext;
142
143
144 byte[] cleartext1 = cipher.doFinal(encryptedData);
145 return cleartext1;
146 }
147
148
149
150
151
152
153
154
155
156 public static String generateEncodedKey() throws Exception {
157 KeyGenerator keygen = KeyGenerator.getInstance("DES");
158 SecretKey desKey = keygen.generateKey();
159
160
161 Cipher cipher = Cipher.getInstance(ALGORITHM);
162 cipher.init((Cipher.WRAP_MODE), desKey);
163
164 SecretKeyFactory desFactory = SecretKeyFactory.getInstance("DES");
165 DESKeySpec desSpec = (DESKeySpec) desFactory.getKeySpec(desKey, javax.crypto.spec.DESKeySpec.class);
166 byte[] rawDesKey = desSpec.getKey();
167
168 return new String(Base64.encodeBase64(rawDesKey));
169 }
170
171 private SecretKey unwrapEncodedKey(String key) throws Exception {
172 KeyGenerator keygen = KeyGenerator.getInstance("DES");
173 SecretKey desKey = keygen.generateKey();
174
175
176 Cipher cipher = Cipher.getInstance(ALGORITHM);
177 cipher.init((Cipher.UNWRAP_MODE), desKey);
178
179 byte[] bytes = Base64.decodeBase64(key.getBytes());
180
181 SecretKeyFactory desFactory = SecretKeyFactory.getInstance("DES");
182
183 DESKeySpec keyspec = new DESKeySpec(bytes);
184 SecretKey k = desFactory.generateSecret(keyspec);
185
186 return k;
187
188 }
189
190
191
192
193
194
195
196 public void setSecretKey(String secretKey) throws Exception {
197 if (!StringUtils.isEmpty(secretKey)) {
198 desKey = this.unwrapEncodedKey(secretKey);
199 isEnabled = true;
200
201 Cipher cipher = Cipher.getInstance(ALGORITHM);
202 cipher.init((Cipher.WRAP_MODE), desKey);
203 }
204 }
205
206
207
208
209
210
211 public String hash(Object valueToHide) throws GeneralSecurityException {
212 if ( valueToHide == null || StringUtils.isEmpty( valueToHide.toString() ) ) {
213 return "";
214 }
215 try {
216 MessageDigest md = MessageDigest.getInstance(HASH_ALGORITHM);
217 return new String( Base64.encodeBase64( md.digest( valueToHide.toString().getBytes( CHARSET ) ) ), CHARSET );
218 } catch ( UnsupportedEncodingException ex ) {
219
220 }
221 return "";
222 }
223
224
225
226
227
228 protected void checkEnabled() {
229 if (!isEnabled()) {
230 throw new IllegalStateException("Illegal use of encryption service. Ecryption service is disabled, to enable please configure 'encryption.key'.");
231 }
232 }
233
234
235
236 }