1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package edu.internet2.middleware.grouperInstaller.morphString;
17
18 import java.io.InputStream;
19 import java.io.OutputStream;
20 import java.security.NoSuchAlgorithmException;
21 import java.util.Base64;
22
23 import javax.crypto.Cipher;
24 import javax.crypto.CipherInputStream;
25 import javax.crypto.CipherOutputStream;
26 import javax.crypto.KeyGenerator;
27 import javax.crypto.SecretKey;
28 import javax.crypto.spec.SecretKeySpec;
29
30 import edu.internet2.middleware.grouperInstaller.util.GrouperInstallerUtils;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class Crypto {
55
56
57
58
59
60
61
62
63 public static byte[] generateKeyBytes(String cipherName, Integer keybits) {
64 KeyGenerator keyGenerator = null;
65 cipherName = cipherName == null ? "AES" : cipherName;
66 try {
67 keyGenerator = KeyGenerator.getInstance(cipherName);
68 } catch (NoSuchAlgorithmException e) {
69 throw new RuntimeException("Failed to create KeyGenerator for cipherName="+cipherName, e);
70 }
71 keyGenerator.init(keybits == null ? 128 : keybits);
72
73
74 SecretKey secretKey = keyGenerator.generateKey();
75 byte[] keyBytes = secretKey.getEncoded();
76
77 return keyBytes;
78 }
79
80
81
82 private SecretKeySpec key;
83
84
85 private Cipher cipher = null;
86
87
88
89
90
91 public Cipher createDefaultCipher() {
92 try {
93 return Cipher.getInstance("AES");
94 } catch(Exception x) {
95 throw new RuntimeException("Failed to create the default cipher!", x);
96 }
97 }
98
99
100
101
102 public Crypto(String theKey) {
103 super();
104 init(theKey);
105 }
106
107
108 private static boolean warned = false;
109
110
111
112
113 protected void init(String secret) {
114
115 if (GrouperInstallerUtils.isBlank(secret)) {
116 throw new NullPointerException("Must supply a non blank encrypt.key");
117 }
118 StringBuilder secretBuilder = new StringBuilder(secret);
119 if (!warned && secret.length() < 8) {
120
121 System.out.println("morphString warning: secret.key in morphString.properties should be at least 8 chars");
122 warned = true;
123 }
124
125 while (secretBuilder.length() < 16) {
126 secretBuilder.append("x");
127 }
128 if (secretBuilder.length() > 16) {
129 while (secretBuilder.length() < 32) {
130 secretBuilder.append("x");
131 }
132 }
133 if (secretBuilder.length() > 32) {
134 secretBuilder.delete(32, secretBuilder.length());
135 }
136 secret = secretBuilder.toString();
137 this.key = new SecretKeySpec(secret.getBytes(), "AES");
138 this.cipher = this.createDefaultCipher();
139 }
140
141
142
143
144
145
146 public String encrypt(String clearText) {
147 byte[] input = clearText.getBytes();
148 try {
149 this.initCipher(true);
150 byte[] output = this.cipher.doFinal(input);
151
152 byte[] encoded = Base64.getEncoder().encode(output);
153 return new String(encoded);
154 } catch(Exception x) {
155 throw new RuntimeException("Failed to encrypt string", x);
156 }
157 }
158
159
160
161
162
163
164 public String decrypt(String cipherText) {
165 try {
166 byte[] cipherBytes = cipherText.getBytes();
167 byte[] decodedBytes = Base64.getDecoder().decode(cipherBytes);
168 this.initCipher(false);
169 byte[] clearBytes = this.cipher.doFinal(decodedBytes);
170 return new String(clearBytes);
171 } catch(Exception x) {
172 throw new RuntimeException("Failed to decrypt the cipherText", x);
173 }
174 }
175
176
177
178
179
180 private void initCipher(boolean encrypt) {
181 try {
182 if ( encrypt ) {
183 this.cipher.init(Cipher.ENCRYPT_MODE, this.key);
184 } else {
185 this.cipher.init(Cipher.DECRYPT_MODE, this.key);
186 }
187 } catch(Exception x) {
188 throw new RuntimeException("Failed to init cipher for "+(encrypt ? "encrypt" : "decrypt"), x);
189 }
190 }
191
192
193
194
195
196
197 public InputStream encrypt(InputStream in) {
198 this.initCipher(true);
199 return new CipherInputStream(in, this.cipher);
200 }
201
202
203
204
205
206
207 public InputStream decrypt(InputStream in) {
208 this.initCipher(false);
209 return new CipherInputStream(in, this.cipher);
210 }
211
212
213
214
215
216
217 public OutputStream encrypt(OutputStream out) {
218 this.initCipher(true);
219 return new CipherOutputStream(out, this.cipher);
220 }
221
222
223
224
225
226
227 public OutputStream decrypt(OutputStream out) {
228 this.initCipher(false);
229 return new CipherOutputStream(out, this.cipher);
230 }
231 }