source: trunk/src/org/expeditee/encryption/Actions.java@ 1494

Last change on this file since 1494 was 1494, checked in by bnemhaus, 4 years ago

Preperation for David's presentation.

File size: 13.4 KB
Line 
1package org.expeditee.encryption;
2
3import java.security.InvalidKeyException;
4import java.security.NoSuchAlgorithmException;
5import java.security.SecureRandom;
6import java.util.Arrays;
7import java.util.Base64;
8import java.util.Collection;
9import java.util.HashMap;
10import java.util.List;
11import java.util.Map;
12import java.util.Random;
13
14import javax.crypto.BadPaddingException;
15import javax.crypto.Cipher;
16import javax.crypto.IllegalBlockSizeException;
17import javax.crypto.NoSuchPaddingException;
18import javax.crypto.SecretKey;
19import javax.crypto.spec.SecretKeySpec;
20
21import org.expeditee.auth.AuthenticatorBrowser;
22import org.expeditee.core.Colour;
23import org.expeditee.gui.DisplayController;
24import org.expeditee.gui.Frame;
25import org.expeditee.gui.FrameIO;
26import org.expeditee.gui.FreeItems;
27import org.expeditee.gui.MessageBay;
28import org.expeditee.items.Item;
29import org.expeditee.items.Text;
30import org.expeditee.settings.UserSettings;
31
32import com.codahale.shamir.Scheme;
33
34public class Actions implements CryptographyConstants {
35
36 public static void SetAsSurrogateFor(Text surrogate, Text action) {
37 Frame frame = DisplayController.getCurrentFrame();
38 String[] split = action.getText().split(" ");
39
40 if (split.length >= 2) {
41 int primaryID = Integer.parseInt(split[1]);
42 Item itemWithID = frame.getItemWithID(primaryID);
43 if (itemWithID == null) {
44 MessageBay.displayMessage("No item with ID " + primaryID + " exists on this frame.");
45 return;
46 } else {
47 itemWithID.addToSurrogates(surrogate);
48 }
49 } else {
50 FreeItems.getInstance().add(SetAsSurrogateForUsage());
51 }
52 }
53
54 public static Text GenerateSecret() {
55 return AuthGenerateSecretUsage();
56 }
57
58 public static Text GenerateSecret(String label) {
59 String nl = System.getProperty("line.separator");
60 String secretsFrame = UserSettings.UserName.get() + 11;
61 StringBuilder instructions = new StringBuilder("You have generated a encryption label with name " + label + "." + nl);
62 instructions.append("Place this generated label on your secrets frame (" + secretsFrame + ") before using it.");
63 MessageBay.displayMessage(instructions.toString()).setLink(secretsFrame);
64 return AuthGenerateSecret(label);
65 }
66
67 public static Text SplitSecret(Text key) {
68 return AuthSplitSecret(key);
69 }
70
71 public static Text JoinSecret() {
72 return AuthJoinSecretUsage();
73 }
74
75 public static Text JoinSecret(Text key) {
76 return AuthJoinSecret(key);
77 }
78
79 public static void Encrypt() {
80 AuthEncryptUsage();
81 }
82
83 public static void Encrypt(Text labelWithKey) {
84 AuthEncrypt(labelWithKey);
85 }
86
87 public static void Decrypt() {
88 AuthDecryptUsage();
89 }
90
91 public static void Decrypt(Text labelWithKey) {
92 AuthDecrypt(labelWithKey);
93 }
94
95 public static Text AuthGenerateSecret() {
96 return AuthGenerateSecretUsage();
97 }
98
99 public static Text AuthGenerateSecret(String label) {
100 // Generate AES Key
101 Random rand = new SecureRandom();
102 byte[] keyBytes = new byte[16];
103 rand.nextBytes(keyBytes);
104 String key = Base64.getEncoder().encodeToString(keyBytes);
105
106 Text text = new Text(label);
107 text.setData(key);
108 text.setPosition(DisplayController.getMousePosition());
109 return text;
110 }
111
112 public static Text AuthSplitSecret(Text key) {
113 if (!FreeItems.hasItemsAttachedToCursor()) {
114 return AuthSplitSecretUsage();
115 }
116
117 // Retrieve secret
118 String secret = key.getData().get(0);
119 byte[] secretBytes = Base64.getDecoder().decode(secret);
120
121 // Obtain parameters for shamir
122 String[] arguments = key.getText().split(" ");
123 int requiredShares = Integer.parseInt(arguments[1]);
124 int totalShares = arguments.length - 2;
125
126 // Create shares
127 Scheme scheme = new Scheme(new SecureRandom(), totalShares, requiredShares);
128 Map<Integer, byte[]> split = scheme.split(secretBytes);
129
130 // Add shares to key
131 List<String> data = key.getData();
132 for (Integer i: split.keySet()) {
133 data.add("{" + i + "}" + Base64.getEncoder().encodeToString(split.get(i)));
134 }
135 key.setData(data);
136 key.setText(arguments[0]);
137
138 return key;
139 }
140
141 public static Text AuthJoinSecret() {
142 return AuthJoinSecretUsage();
143 }
144
145 public static Text AuthJoinSecret(Text key) {
146 Map<Integer, byte[]> contributingParts = new HashMap<Integer, byte[]>();
147
148 // Retrieve splits
149 List<String> data = key.getData();
150 for (String d: data) {
151 if (d.startsWith("{")) {
152 String[] split = d.split("}");
153 Integer k = Integer.parseInt(split[0].replace("{", ""));
154 byte[] v = Base64.getDecoder().decode(split[1]);
155 contributingParts.put(k, v);
156 }
157 }
158
159 // Obtain parameters for shamir
160 String[] arguments = key.getText().split(" ");
161 int totalShares = Integer.parseInt(arguments[2]);
162 int requiredShares = Integer.parseInt(arguments[1]);
163
164 // Perform join
165 Scheme scheme = new Scheme(new SecureRandom(), totalShares, requiredShares);
166 byte[] join = scheme.join(contributingParts);
167
168 data.clear();
169 data.add(Base64.getEncoder().encodeToString(join));
170
171 return key;
172 }
173
174 public static void AuthEncrypt(Text labelWithKey) {
175 try {
176 // Obtain encryption key
177 String keyEncoded = labelWithKey.getData().get(0);
178 byte[] keyDecoded = Base64.getDecoder().decode(keyEncoded);
179 SecretKey key = new SecretKeySpec(keyDecoded, SymmetricAlgorithm);
180
181 // Perform encryption
182 Frame toEncrypt = FrameIO.LoadFrame(labelWithKey.getLink());
183 Collection<Text> textItems = toEncrypt.getTextItems();
184 for (Text t: textItems) {
185 byte[] encrypted = EncryptSymmetric(t.getText().getBytes(), key);
186 t.setText(Base64.getEncoder().encodeToString(encrypted));
187 }
188
189 // Save changes
190 FrameIO.SaveFrame(toEncrypt);
191 } catch (Exception e) {
192 FreeItems.getInstance().add(AuthEncryptUsage());
193 }
194 }
195
196 public static void AuthDecrypt(Text labelWithKey) {
197 try {
198 // Obtain encryption key
199 String keyEncoded = labelWithKey.getData().get(0);
200 byte[] keyDecoded = Base64.getDecoder().decode(keyEncoded);
201 SecretKey key = new SecretKeySpec(keyDecoded, SymmetricAlgorithm);
202
203 // Perform decryption
204 Frame toDecrypt = FrameIO.LoadFrame(labelWithKey.getLink());
205 Collection<Text> textItems = toDecrypt.getTextItems();
206 for (Text t: textItems) {
207 byte[] decrypted = DecryptSymmetric(Base64.getDecoder().decode(t.getText().getBytes()), key);
208 t.setText(new String(decrypted));
209 }
210
211 // Save changes
212 FrameIO.SaveFrame(toDecrypt);
213 } catch (Exception e) {
214 FreeItems.getInstance().add(AuthDecryptUsage());
215 }
216 }
217
218 public static byte[] EncryptSymmetric(final byte[] toEncrypt, final SecretKey key) {
219 // toEncrypt = Base64.getDecoder().decode(toEncrypt);
220 try {
221 final Cipher cipher = Cipher.getInstance(SymmetricAlgorithm + SymmetricAlgorithmParameters);
222 cipher.init(Cipher.ENCRYPT_MODE, key);
223 //could use modulus
224 final int length = (int) ((Math.ceil(toEncrypt.length / 16f)) * 16);
225 final byte[] toEncryptSizeAdjusted = Arrays.copyOf(toEncrypt, length);
226 //System.err.println("(" + toEncryptSizeAdjusted.length + ")" + "Before Encryption Data: "
227 // + Arrays.toString(toEncryptSizeAdjusted));
228 final byte[] result = cipher.doFinal(toEncryptSizeAdjusted);
229 //System.err.println("(" + result.length + ")" + "Encrypted Data: " + Arrays.toString(result));
230 return result;
231 } catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
232 | IllegalBlockSizeException | BadPaddingException e) {
233 e.printStackTrace();
234 return null;
235 }
236 }
237
238 public static byte[] DecryptSymmetric(final byte[] toDecrypt, final SecretKey key) {
239 try {
240 final Cipher cipher = Cipher.getInstance(SymmetricAlgorithm + SymmetricAlgorithmParameters);
241 cipher.init(Cipher.DECRYPT_MODE, key);
242 final byte[] decryptedBytes = cipher.doFinal(toDecrypt);
243 int indexOfZero = decryptedBytes.length - 1;
244 for (int i = decryptedBytes.length - 1; i >= 0; i--) {
245 if (decryptedBytes[i] != (byte) 0) {
246 indexOfZero = i + 1;
247 break;
248 }
249 }
250 return Arrays.copyOf(decryptedBytes, indexOfZero);
251 } catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
252 | IllegalBlockSizeException | BadPaddingException e) {
253 e.printStackTrace();
254 return null;
255 }
256 }
257
258 public static void AuthAddSecretKey(String name, String data) {
259 String frameName = UserSettings.UserName.get() + AuthenticatorBrowser.SECRETS_FRAME;
260 Frame secretsFrame = FrameIO.LoadFrame(frameName);
261 secretsFrame.addText(500, 500, name, null).addToData(data);
262 FrameIO.ForceSaveFrame(secretsFrame);
263 MessageBay.displayMessage("Your half of " + name + "'s personal key has been added to " + frameName);
264 }
265
266 private static Text AuthJoinSecretUsage() {
267 String nl = System.getProperty("line.separator");
268 String tab = " ";
269 StringBuilder message = new StringBuilder("Usage: " + nl);
270 message.append(tab + "With Text Item attached to cursor: " + nl);
271 message.append(tab + tab + "Content matches pattern \"<SecretName> <Amount of Coperation Required> <Total Number of Shares>\"" + nl);
272 message.append(tab + tab + "Data contains <Amount of Coperation Required> partial keys" + nl);
273 message.append(tab + "Left click on this action." + nl);
274 message.append(tab + "Resulting Text Item will contain joined key in data.");
275 return generateUsageText(message);
276 }
277
278 private static Text AuthSplitSecretUsage() {
279 String nl = System.getProperty("line.separator");
280 String tab = " ";
281 StringBuilder message = new StringBuilder("Usage: " + nl);
282 message.append(tab + "With Text Item attached to cursor: " + nl);
283 message.append(tab + tab + "Content matches pattern \"<SecretName> <Amount of Coperation Required> <Individual Name 1> <Individual Name 2> ... <Individual Name N>\"" + nl);
284 message.append(tab + tab + "Context Example: \"SecretName 3 Sandra John Billy Sally Sam Tim\"" + nl);
285 message.append(tab + tab + "Data contains key data" + nl);
286 message.append(tab + "Left click on this action." + nl);
287 message.append(tab + "Resulting Text Item will contain shares in data.");
288 return generateUsageText(message);
289 }
290
291 private static Text AuthGenerateSecretUsage() {
292 String nl = System.getProperty("line.separator");
293 String tab = " ";
294 StringBuilder message = new StringBuilder("Usage: " + nl);
295 message.append(tab + "With Text Item attached to cursor: " + nl);
296 message.append(tab + tab + "Content should be one word with no spaces." + nl);
297 message.append(tab + tab + "Content represents the desired label name for the generated secret." + nl);
298 message.append(tab + tab + "This action will overwrite any existing data." + nl);
299 message.append(tab + "Left click on this action." + nl);
300 message.append(tab + "Text Item will now contain a full key in its data." + nl);
301 message.append(tab + "Resulting Text Item is now a Secret and can be placed on secrets frame.");
302 return generateUsageText(message);
303 }
304
305 private static Text AuthEncryptUsage() {
306 String nl = System.getProperty("line.separator");
307 String tab = " ";
308 StringBuilder message = new StringBuilder("Usage: " + nl);
309 message.append(tab + "Note: this action was used for demonstration purposes earlier in development." + nl);
310 message.append(tab + "(It can now be considered deprecated by Encryption Label and surrogate functionality)" + nl);
311 message.append(tab + "With Text Item attached to cursor: " + nl);
312 message.append(tab + tab + "Data contains key data." + nl);
313 message.append(tab + tab + "Must be linked to frame you wish to encrypt." + nl);
314 message.append(tab + "Left click on this action." + nl);
315 message.append(tab + "Content on linked frame will now be encrypted.");
316 return generateUsageText(message);
317 }
318
319 private static Text AuthDecryptUsage() {
320 String nl = System.getProperty("line.separator");
321 String tab = " ";
322 StringBuilder message = new StringBuilder("Usage: " + nl);
323 message.append(tab + "Note: this action was used for demonstration purposes earlier in development." + nl);
324 message.append(tab + "(It can now be considered deprecated by Encryption Label and surrogate functionality)" + nl);
325 message.append(tab + "With Text Item attached to cursor: " + nl);
326 message.append(tab + tab + "Data contains key data." + nl);
327 message.append(tab + tab + "Must be linked to frame that was previously encrypted." + nl);
328 message.append(tab + "Left click on this action." + nl);
329 message.append(tab + "Content on linked frame will now be decrypted.");
330 return generateUsageText(message);
331 }
332
333 private static Text SetAsSurrogateForUsage() {
334 String nl = System.getProperty("line.separator");
335 String tab = " ";
336 StringBuilder message = new StringBuilder("Usage: " + nl);
337 message.append(tab + "Change arugment to be the ID of the desired primary item." + nl);
338 message.append(tab + "(An items ID is available in its extracted properties)" + nl);
339 message.append(tab + "With Text Item attached to cursor: " + nl);
340 message.append(tab + tab + "Attached Item is desired surrogate." + nl);
341 message.append(tab + "Left click on this action." + nl);
342 message.append(tab + "Item will respect surrogate mode once placed on frame." + nl);
343 return generateUsageText(message);
344 }
345
346 private static Text generateUsageText(StringBuilder message) {
347 Text ret = new Text(message.toString());
348 ret.setPosition(DisplayController.getMousePosition());
349 ret.setSize(14);
350 ret.setBackgroundColor(Colour.LIGHT_GRAY);
351 ret.setBorderColor(Colour.DARK_GRAY);
352 return ret;
353 }
354}
Note: See TracBrowser for help on using the repository browser.