Changeset 1202 for trunk/src/org/expeditee/auth
- Timestamp:
- 01/30/19 12:49:25 (5 years ago)
- Location:
- trunk/src/org/expeditee/auth
- Files:
-
- 3 added
- 1 deleted
- 1 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/auth/Authenticator.java
r1201 r1202 5 5 import java.io.FileNotFoundException; 6 6 import java.io.FileOutputStream; 7 import java.io.FileWriter; 7 8 import java.io.IOException; 8 9 import java.io.InputStream; 10 import java.io.Writer; 11 import java.security.KeyFactory; 9 12 import java.security.KeyStore; 10 13 import java.security.KeyStore.SecretKeyEntry; 11 14 import java.security.KeyStoreException; 12 15 import java.security.NoSuchAlgorithmException; 16 import java.security.PublicKey; 17 import java.security.SecureRandom; 13 18 import java.security.UnrecoverableEntryException; 14 19 import java.security.cert.CertificateException; 20 import java.security.spec.InvalidKeySpecException; 21 import java.security.spec.X509EncodedKeySpec; 22 import java.sql.Connection; 23 import java.sql.DriverManager; 24 import java.sql.ResultSet; 25 import java.sql.SQLException; 26 import java.sql.Statement; 27 import java.util.Arrays; 28 import java.util.Base64; 29 import java.util.Collection; 30 import java.util.HashMap; 31 import java.util.Map; 32 import java.util.stream.Stream; 15 33 16 34 import javax.crypto.SecretKey; 17 35 import javax.crypto.spec.SecretKeySpec; 36 37 import org.expeditee.actions.Actions; 38 import org.expeditee.core.Dimension; 39 import org.expeditee.core.Point; 40 import org.expeditee.gio.EcosystemManager; 41 import org.expeditee.gio.GraphicsManager; 42 import org.expeditee.gio.InputManager; 43 import org.expeditee.gio.InputManager.WindowEventListener; 44 import org.expeditee.gio.InputManager.WindowEventType; 45 import org.expeditee.gio.gesture.StandardGestureActions; 46 import org.expeditee.gui.Browser; 47 import org.expeditee.gui.DisplayController; 48 import org.expeditee.gui.Frame; 18 49 import org.expeditee.gui.FrameIO; 50 import org.expeditee.gui.FrameUtils; 51 import org.expeditee.gui.MessageBay; 52 import org.expeditee.items.ItemUtils; 53 import org.expeditee.items.Text; 54 import org.expeditee.settings.Settings; 55 import org.expeditee.settings.UserSettings; 56 import org.expeditee.settings.auth.secrets.KeyList; 19 57 import org.ngikm.cryptography.CryptographyConstants; 20 58 21 59 public final class Authenticator implements CryptographyConstants { 22 final KeyStore keyStore = KeyStore.getInstance(KeystoreType); 23 private static final String keystoreFileName = FrameIO.PARENT_FOLDER + "keystore.ks" + File.separator; 24 25 public Authenticator() throws KeyStoreException, FileNotFoundException, IOException, NoSuchAlgorithmException, CertificateException { 26 final File keyStoreFile = new File(keystoreFileName); 60 61 // The frame number of the frame containing the current authenticated users public key. 62 public static final int PUBLIC_KEY_FRAME = 4; 63 64 private final KeyStore keyStore = KeyStore.getInstance(KeystoreType); 65 private static final byte[] TRUE = "yes".getBytes(); 66 private static final byte[] FALSE = "no".getBytes(); 67 private static final String KEYSTOREFILENAME = "keystore.ks" + File.separator; 68 69 private static Authenticator instance; 70 71 public static Authenticator getInstance() throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, IOException, ClassNotFoundException, SQLException { 72 if (instance == null) { instance = new Authenticator(); } 73 return instance; 74 } 75 76 private Authenticator() throws KeyStoreException, FileNotFoundException, IOException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, SQLException { 77 UserSettings.setupDefaultFolders(); 78 79 // initialise keystore and actions 80 loadKeystore(); 81 Actions.LoadMethods(org.expeditee.auth.Actions.class); 82 83 // draw the window 84 final GraphicsManager g = EcosystemManager.getGraphicsManager(); 85 g.setWindowLocation(new Point(50, 50)); 86 DisplayController.Init(); 87 g.setWindowSize(new Dimension(UserSettings.InitialWidth.get(), UserSettings.InitialHeight.get())); 88 setInputManagerWindowRoutines(); 89 90 // Load documentation and start pages 91 FrameUtils.extractResources(false); 92 93 // Load fonts before loading any frames so the items on the frames will be able to access their fonts 94 Text.InitFonts(); 95 96 // initialing settings does not require a user profile established 97 Settings.Init(); 98 99 // navigate to authentication frame 100 final Frame authFrame = FrameIO.LoadFrame("authentication1"); 101 DisplayController.setCurrentFrame(authFrame, true); 102 103 // set initial values 104 final Stream<Text> usernameItemsStream = authFrame.getTextItems().stream().filter(t -> t.getData() != null && t.getData().contains("txtUsername")); 105 final Stream<Text> passwordItemsStream = authFrame.getTextItems().stream().filter(t -> t.getData() != null && t.getData().contains("txtPassword")); 106 usernameItemsStream.forEach(txtUsername -> txtUsername.setText(System.getProperty("user.name", ""))); 107 passwordItemsStream.forEach(txtPassword -> txtPassword.setText(System.getProperty("user.password", ""))); 108 109 MessageBay.warningMessages(org.expeditee.actions.Actions.Init()); 110 111 // ensure database 112 Class.forName("org.sqlite.JDBC"); 113 if (!mailDatabaseExists()) { 114 createMailDatabase(); 115 } 116 } 117 118 private void createMailDatabase() throws ClassNotFoundException, SQLException { 119 Connection c = DriverManager.getConnection("jdbc:sqlite:" + FrameIO.PARENT_FOLDER + "/expmail.db"); 120 Statement createTable = c.createStatement(); 121 String sql = "CREATE TABLE EXPMAIL (" + 122 "SND TEXT NOT NULL, " + 123 "REC TEXT NOT NULL, " + 124 "MSG TEXT NOT NULL, " + 125 "MSG2 TEXT NOT NULL, " + 126 "OPTS ARRAY NOT NULL, " + 127 "OPTSVAL ARRAY NOT NULL)"; 128 createTable.executeUpdate(sql); 129 createTable.close(); 130 c.close(); 131 } 132 133 final void loadMailDatabase() throws SQLException { 134 Connection c = DriverManager.getConnection("jdbc:sqlite:" + FrameIO.PARENT_FOLDER + "/expmail.db"); 135 Statement query = c.createStatement(); 136 ResultSet results = query.executeQuery("SELECT * FROM EXPMAIL"); 137 Mail.clear(); 138 while (results.next()) { 139 String from = results.getString("snd"); 140 String to = results.getString("rec"); 141 String msg = results.getString("msg"); 142 String msg2 = results.getString("msg2"); 143 String[] opts = results.getString("opts").split(","); 144 opts[0] = opts[0].replace("[", ""); 145 opts[opts.length - 1] = opts[opts.length - 1].replace("]", ""); 146 String[] optsVal = results.getString("optsval").split(","); 147 optsVal[0] = optsVal[0].replace("[", ""); 148 optsVal[optsVal.length - 1] = optsVal[optsVal.length - 1].replace("]", ""); 149 150 Map<String, String> options = new HashMap<String, String>(); 151 for (int i = 0, o = 0; i < opts.length && o < optsVal.length; i++, o++) { 152 String key = opts[i].trim(); 153 String val = optsVal[o].trim(); 154 options.put(key, val); 155 } 156 157 Mail.addEntry(new Mail.MailEntry(from, to, msg, msg2, options)); 158 } 159 results.close(); 160 query.close(); 161 c.close(); 162 } 163 164 private boolean mailDatabaseExists() { 165 final File file = new File(FrameIO.PARENT_FOLDER + "/expmail.db"); 166 return file.exists(); 167 } 168 169 private void loadKeystore() 170 throws IOException, NoSuchAlgorithmException, CertificateException, FileNotFoundException { 171 final File keyStoreFile = new File(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME); 27 172 if (!keyStoreFile.exists()) { 28 173 keyStore.load(null, "ExpediteeAuthPassword".toCharArray()); 29 174 } else { 30 try (final InputStream in = new FileInputStream( keystoreFileName)) {175 try (final InputStream in = new FileInputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME)) { 31 176 keyStore.load(in, "ExpediteeAuthPassword".toCharArray()); 32 177 } … … 34 179 } 35 180 36 public final SecretKey getSecretKey(final String label, final String password) throws NoSuchAlgorithmException, UnrecoverableEntryException, KeyStoreException {181 final SecretKey getSecretKey(final String label, final String password) throws NoSuchAlgorithmException, KeyStoreException { 37 182 final KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(password.toCharArray()); 38 final KeyStore.SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(label, entryPassword); 183 KeyStore.SecretKeyEntry entry = null; 184 try { 185 entry = (SecretKeyEntry) keyStore.getEntry(label, entryPassword); 186 } catch (final UnrecoverableEntryException e) { 187 entry = null; 188 } 39 189 if (entry == null) { return null; } 40 190 else { return entry.getSecretKey(); } 41 191 } 42 192 43 publicfinal void putKey(final String label, final String password, final SecretKey key) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException {193 final void putKey(final String label, final String password, final SecretKey key) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException { 44 194 final KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(key); 45 195 final KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(password.toCharArray()); 46 196 keyStore.setEntry(label, entry, entryPassword); 47 keyStore.store(new FileOutputStream(keystoreFileName), "ExpediteeAuthPassword".toCharArray()); 197 keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray()); 198 } 199 200 final void putEmail(String username, String email) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException { 201 // Establish location of email file 202 String emailFilePath = FrameIO.PROFILE_PATH + username + File.separator + username + ".email"; 203 File emailFile = new File(emailFilePath); 204 205 // Delete old version if it exists. 206 if (emailFile.exists()) { 207 emailFile.delete(); 208 } 209 210 // Write email to file 211 emailFile.createNewFile(); 212 Writer w = new FileWriter(emailFile); 213 w.write(email); 214 w.flush(); 215 w.close(); 216 217 // TODO: set rights on file to be read only by 'owner' once installed on drive. 218 } 219 220 final boolean hasRegisteredEmail(String username) throws KeyStoreException { 221 String emailFilePath = FrameIO.PROFILE_PATH + username + File.separator + username + ".email"; 222 File emailFile = new File(emailFilePath); 223 return emailFile.exists(); 224 } 225 226 final boolean confirmIntergalaticNumber(final String username, final String email, final String intergalacticNumber) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, FileNotFoundException, IOException { 227 try { 228 final KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(intergalacticNumber.toCharArray()); 229 final KeyStore.SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(email + username, entryPassword); 230 if (entry == null) { 231 return false; 232 } else if (entry.getSecretKey().getEncoded() == TRUE) { 233 keyStore.deleteEntry(email + username); 234 keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray()); 235 return true; 236 } else { return false; } 237 } catch (final UnrecoverableEntryException e) { 238 return false; 239 } 240 } 241 242 final String newIntergalacticNumber(final String username, final String email) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException { 243 // generate intergalactic number 244 final SecureRandom rand = new SecureRandom(); 245 final byte[] intergalacticNumberBytes = new byte[20]; 246 rand.nextBytes(intergalacticNumberBytes); 247 final String intergalacticNumber = Base64.getEncoder().encodeToString(intergalacticNumberBytes); 248 249 // store intergalactic number 250 final KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(TRUE, SymmetricAlgorithm)); 251 final KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(intergalacticNumber.toCharArray()); 252 keyStore.setEntry(email + username, entry, entryPassword); 253 keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray()); 254 255 return intergalacticNumber; 256 } 257 258 final PublicKey getPublicKey(String username) throws InvalidKeySpecException, NoSuchAlgorithmException { 259 Frame withTargetPublic = FrameIO.LoadFrame(username + Authenticator.PUBLIC_KEY_FRAME); 260 Collection<Text> textItems = withTargetPublic.getTextItems(); 261 textItems.removeIf(t -> !t.getText().startsWith("PublicKey")); 262 263 if (textItems.isEmpty()) { 264 return null; 265 } else { 266 String keyEncoded = textItems.stream().findFirst().get().getData().get(0); 267 byte[] keyBytes = Base64.getDecoder().decode(keyEncoded); 268 PublicKey key = KeyFactory.getInstance(AsymmetricAlgorithm).generatePublic(new X509EncodedKeySpec(keyBytes)); 269 return key; 270 } 271 } 272 273 final void markRequestedColleagues(String username) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException { 274 KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(TRUE, SymmetricAlgorithm)); 275 KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray()); 276 keyStore.setEntry(username + "colleaguesRequested", entry, entryPassword); 277 keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray()); 278 } 279 280 final void clearRequestedColleagues(String username) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException { 281 KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(FALSE, SymmetricAlgorithm)); 282 KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray()); 283 keyStore.setEntry(username + "colleaguesRequested", entry, entryPassword); 284 keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray()); 285 } 286 287 final boolean hasRequestedColleagues(String username) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException { 288 String alias = username + "colleaguesRequested"; 289 if (!keyStore.containsAlias(alias)) { 290 return false; 291 } else { 292 KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray()); 293 KeyStore.SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(alias, entryPassword); 294 return Arrays.equals(entry.getSecretKey().getEncoded(), TRUE); 295 } 296 } 297 298 final void putColleagues(String username, String[] colleagues) throws KeyStoreException { 299 String alias = username + "colleagues"; 300 final SecretKeySpec secretKeySpec = new SecretKeySpec((colleagues[0] + System.getProperty("line.separator") + colleagues[1]).getBytes(), SymmetricAlgorithm); 301 KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(secretKeySpec); 302 KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray()); 303 keyStore.setEntry(alias, entry, entryPassword); 304 } 305 306 final String[] getColleagues(String username) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException { 307 String alias = username + "colleagues"; 308 if (!keyStore.containsAlias(alias)) { 309 return null; 310 } else { 311 KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray()); 312 KeyStore.SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(alias, entryPassword); 313 byte[] colleaguesEncoded = entry.getSecretKey().getEncoded(); 314 String colleagues = new String(colleaguesEncoded); 315 return colleagues.split(System.getProperty("line.separator")); 316 } 317 } 318 319 private static void setInputManagerWindowRoutines() { 320 InputManager manager = EcosystemManager.getInputManager(); 321 322 // Refresh the layout when the window resizes 323 manager.addWindowEventListener(new WindowEventListener() { 324 @Override 325 public void onWindowEvent(WindowEventType type) 326 { 327 if (type != WindowEventType.WINDOW_RESIZED) { 328 return; 329 } 330 DisplayController.refreshWindowSize(); 331 FrameIO.RefreshCacheImages(); 332 for (Frame frame : DisplayController.getFrames()) { 333 if (frame != null) { 334 ItemUtils.Justify(frame); 335 frame.refreshSize(); 336 } 337 } 338 DisplayController.requestRefresh(false); 339 } 340 }); 341 342 manager.addWindowEventListener(new WindowEventListener() { 343 @Override 344 public void onWindowEvent(WindowEventType type) 345 { 346 if (type != WindowEventType.MOUSE_EXITED_WINDOW) { 347 return; 348 } 349 StandardGestureActions.mouseExitedWindow(); 350 } 351 }); 352 353 manager.addWindowEventListener(new WindowEventListener() { 354 @Override 355 public void onWindowEvent(WindowEventType type) 356 { 357 if (type != WindowEventType.MOUSE_ENTERED_WINDOW) { 358 return; 359 } 360 StandardGestureActions.mouseEnteredWindow(); 361 } 362 }); 363 364 manager.addWindowEventListener(new WindowEventListener() { 365 @Override 366 public void onWindowEvent(WindowEventType type) 367 { 368 if (type != WindowEventType.WINDOW_CLOSED) { 369 return; 370 } 371 if (Browser._theBrowser != null) { 372 Browser._theBrowser.exit(); 373 } 374 } 375 }); 48 376 } 49 377 } -
trunk/src/org/expeditee/auth/EncryptedExpReader.java
r1201 r1202 1 package org.expeditee.auth .io;1 package org.expeditee.auth; 2 2 3 3 import java.io.BufferedReader; 4 4 import java.io.FileInputStream; 5 import java.io.FileReader; 5 6 import java.io.IOException; 6 7 import java.io.InputStreamReader; … … 19 20 import javax.crypto.NoSuchPaddingException; 20 21 import javax.crypto.SecretKey; 21 22 import org.expeditee.auth.Authenticator; 22 import javax.crypto.spec.SecretKeySpec; 23 23 24 import org.expeditee.gui.Frame; 24 25 import org.expeditee.io.ExpReader; 26 import org.expeditee.items.Text; 27 import org.expeditee.settings.auth.secrets.KeyList; 25 28 import org.ngikm.Util.ThrowingFunction; 26 29 import org.ngikm.cryptography.CryptographyConstants; … … 28 31 public class EncryptedExpReader extends ExpReader implements CryptographyConstants { 29 32 static final String ENCRYPTED_EXP_FLAG = "EncryptedExp"; 30 private List<SecretKey> keys; 31 32 public EncryptedExpReader(final String frameName) throws UnsupportedEncodingException { 33 private SecretKey personalKey; 34 private List<SecretKey> multiKey; 35 private boolean accessDenied = false; 36 private boolean usePersonalKey; 37 38 public EncryptedExpReader(final String frameName, final boolean usePersonalKey) throws UnsupportedEncodingException { 33 39 super(frameName); 40 this.usePersonalKey = usePersonalKey; 34 41 } 35 42 … … 41 48 } 42 49 50 public int getVersionEnc(String fullpath) { 51 try { 52 BufferedReader reader; 53 if (usePersonalKey) { 54 reader = new EncryptedProfileLineReader(new BufferedReader(new FileReader(fullpath))); 55 } else { 56 reader = new EncryptedLineReader(new BufferedReader(new FileReader(fullpath))); 57 } 58 String next = ""; 59 // First read the header lines until we get the version number 60 while (reader.ready() && !(next = reader.readLine()).equals("Z")) { 61 if (isValidLine(next)) { 62 Character tag = getTag(next); 63 String value = getValue(next); 64 if (tag.equals('V')) { 65 reader.close(); 66 return Integer.parseInt(value); 67 } 68 } 69 } 70 reader.close(); 71 } catch (Exception e) { 72 } 73 return -1; 74 } 75 43 76 @Override 44 77 public Frame readFrame(final String fullPath) throws IOException { 45 78 final Reader in = new InputStreamReader(new FileInputStream(fullPath), "UTF-8"); 46 return readFrame(new EncryptedLineReader(new BufferedReader(in))); 47 } 48 49 public class EncryptedLineReader extends BufferedReader { 50 51 public EncryptedLineReader(final Reader in) { 52 super(in); 53 } 54 55 @Override 56 public String readLine() throws IOException { 57 final String line = super.readLine(); 58 if (line.isEmpty()) { return ""; } 59 if (line.startsWith(ENCRYPTED_EXP_FLAG)) { 60 try { 61 // resolve labels to secret keys 62 final List<String> labels = Arrays.asList(line.split(" ")).stream().skip(1).collect(Collectors.toList()); 63 final Authenticator auth = new Authenticator(); 64 final ThrowingFunction<String, SecretKey, Exception> worker = new ThrowingFunction<String, SecretKey, Exception>() { 65 @Override 66 public SecretKey applyThrows(final String label) throws Exception { 67 return auth.getSecretKey(label, System.getProperty("password")); 68 } 69 }; 70 keys = labels.stream().map(worker).collect(Collectors.toList()); 71 return readLine(); 72 } catch (final Exception e) { 73 return ""; 74 } 75 } 76 77 if (keys == null) { 78 // We do not have permission to view this frame. 79 return ""; 80 } 81 82 // use keys to decrypt 83 byte[] toDecrypt = Base64.getDecoder().decode(line); 84 for (final SecretKey key: keys) { 85 toDecrypt = DecryptSymmetric(toDecrypt, key); 86 } 87 final String result = new String(toDecrypt); 88 if (result.startsWith("Z")) { return result.trim(); } 89 else { return result; } 90 } 79 if (usePersonalKey) { 80 return readFrame(new EncryptedProfileLineReader(new BufferedReader(in))); 81 } else { 82 return readFrame(new EncryptedLineReader(new BufferedReader(in))); 83 } 84 } 85 86 @Override 87 public Frame readFrame(final BufferedReader reader) throws IOException { 88 if (accessDenied) { return null; } 89 else return super.readFrame(reader); 91 90 } 92 91 … … 111 110 } 112 111 } 112 113 private class EncryptedProfileLineReader extends BufferedReader { 114 115 public EncryptedProfileLineReader(final Reader in) { 116 super(in); 117 } 118 119 @Override 120 /** 121 * Reads a line from an encrypted exp file that uses profile encryption (single key; personal key) 122 * Returns that line to process, null if the currently logged in users personal key is not the appropriate one (access denied). 123 */ 124 public String readLine() throws IOException { 125 // read encrypted line 126 final String line = super.readLine(); 127 128 if (line.isEmpty()) { return ""; } 129 if (line.startsWith(ENCRYPTED_EXP_FLAG)) { 130 // record/overwrite previous personal key then ignore this line by recursing 131 final Text text = KeyList.PersonalKey.get(); 132 final byte[] keyBytes = Base64.getDecoder().decode(text.getData().get(0)); 133 personalKey = new SecretKeySpec(keyBytes, SymmetricAlgorithm); 134 return readLine(); 135 } 136 137 // decrypt line and return result 138 final byte[] toDecrypt = Base64.getDecoder().decode(line); 139 final byte[] decrypted = DecryptSymmetric(toDecrypt, personalKey); 140 if (decrypted == null) { 141 accessDenied = true; 142 return null; // access denied 143 } else { 144 final String decryptedLine = new String(decrypted); 145 if (decryptedLine.startsWith("Z")) { return decryptedLine.trim(); } 146 else { return decryptedLine; } 147 } 148 } 149 } 150 151 private class EncryptedLineReader extends BufferedReader { 152 153 public EncryptedLineReader(final Reader in) { 154 super(in); 155 } 156 157 @Override 158 /** 159 * Reads a line from an encrypted exp file that uses (potentially multiple) labeled keys 160 * Returns that line to process, null if the ... 161 */ 162 public String readLine() throws IOException { 163 // read encrypted line 164 final String line = super.readLine(); 165 166 if (line.isEmpty()) { return ""; } 167 if (line.startsWith(ENCRYPTED_EXP_FLAG)) { 168 // resolve labels to secret keys 169 final List<String> labels = Arrays.asList(line.split(" ")).stream().skip(1).collect(Collectors.toList()); 170 final ThrowingFunction<String, SecretKey, Exception> worker = new ThrowingFunction<String, SecretKey, Exception>() { 171 @Override 172 public SecretKey applyThrows(final String label) throws Exception { 173 return Authenticator.getInstance().getSecretKey(label, System.getProperty("password")); 174 } 175 }; 176 multiKey = labels.stream().map(l -> { 177 try { 178 return worker.apply(l); 179 } catch (final Exception e) { 180 return null; 181 } 182 }).collect(Collectors.toList()); 183 184 // confirm you have all the keys necessary for decryption 185 if (multiKey.contains(null)) { 186 return null; 187 } 188 189 // move onto the next line 190 return readLine(); 191 } 192 193 // decrypt line and return result 194 final byte[] toDecrypt = Base64.getDecoder().decode(line); 195 byte[] decryptedBytes = null; 196 for (final SecretKey key: multiKey) { 197 decryptedBytes = DecryptSymmetric(toDecrypt, key); 198 if (decryptedBytes == null) { return null; } 199 } 200 final String decrypted = new String(decryptedBytes); 201 if (decrypted.startsWith("Z")) { return decrypted.trim(); } 202 else { return decrypted; } 203 } 204 } 113 205 } -
trunk/src/org/expeditee/auth/EncryptedProfileExpWriter.java
r1201 r1202 1 package org.expeditee.auth .io;1 package org.expeditee.auth; 2 2 3 3 import java.io.IOException; 4 4 import java.security.InvalidKeyException; 5 import java.security.KeyStoreException;6 5 import java.security.NoSuchAlgorithmException; 7 import java.security.UnrecoverableEntryException;8 import java.security.cert.CertificateException;9 6 import java.util.Arrays; 10 7 import java.util.Base64; … … 17 14 import javax.crypto.spec.SecretKeySpec; 18 15 19 import org.expeditee.auth.Authenticator;20 16 import org.expeditee.io.ExpWriter; 21 import org.expeditee.settings.UserSettings; 17 import org.expeditee.items.Text; 18 import org.expeditee.settings.auth.secrets.KeyList; 22 19 import org.ngikm.cryptography.CryptographyConstants; 23 20 24 public class Encrypted ExpWriter extends ExpWriter implements CryptographyConstants {25 private SecretKey key;21 public class EncryptedProfileExpWriter extends ExpWriter implements CryptographyConstants { 22 private SecretKey personalKey; 26 23 private static final String nl = "\n"; 27 24 28 public EncryptedExpWriter() throws IOException { 29 try { 30 final Authenticator auth = new Authenticator(); 31 SecretKey key = auth.getSecretKey(UserSettings.UserName.get(), System.getProperty("password")); 32 if (key == null) { 33 final byte[] keyBytes = pad(UserSettings.UserName.get().getBytes("UTF-8")); 34 key = new SecretKeySpec(keyBytes, SymmetricAlgorithm); 35 auth.putKey(UserSettings.UserName.get(), System.getProperty("password"), key); 36 } 37 this.key = key; 38 } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException | UnrecoverableEntryException e) { 39 e.printStackTrace(); 40 } 41 25 public EncryptedProfileExpWriter() throws IOException { 26 // obtain personal key 27 final Text text = KeyList.PersonalKey.get(); 28 final byte[] keyBytes = Base64.getDecoder().decode(text.getData().get(0)); 29 personalKey = new SecretKeySpec(keyBytes, SymmetricAlgorithm); 42 30 } 43 31 … … 45 33 protected void preOutputFrame() { 46 34 try { 47 final String line = EncryptedExpReader.ENCRYPTED_EXP_FLAG + " " + UserSettings.UserName.get() +nl;35 final String line = EncryptedExpReader.ENCRYPTED_EXP_FLAG + nl; 48 36 _writer.write(line); 49 37 _stringWriter.append(line); … … 59 47 60 48 // prepare line to write out 61 final byte[] encrypted = EncryptSymmetric(line.getBytes(), key);49 final byte[] encrypted = EncryptSymmetric(line.getBytes(), personalKey); 62 50 final String toWrite = Base64.getEncoder().encodeToString(encrypted) + nl; 63 51 … … 67 55 } 68 56 69 private byte[] pad(final byte[] bytes) {70 int c = 16;71 while (c - bytes.length < 0) { c *= 2; }72 return Arrays.copyOf(bytes, c);73 }74 75 57 private static byte[] EncryptSymmetric(final byte[] toEncrypt, final SecretKey key) { 76 // toEncrypt = Base64.getDecoder().decode(toEncrypt);77 58 try { 78 59 final Cipher cipher = Cipher.getInstance(SymmetricAlgorithm + SymmetricAlgorithmParameters); … … 81 62 final int length = (int) ((Math.ceil(toEncrypt.length / 16f)) * 16); 82 63 final byte[] toEncryptSizeAdjusted = Arrays.copyOf(toEncrypt, length); 83 //System.err.println("(" + toEncryptSizeAdjusted.length + ")" + "Before Encryption Data: "84 // + Arrays.toString(toEncryptSizeAdjusted));85 64 final byte[] result = cipher.doFinal(toEncryptSizeAdjusted); 86 //System.err.println("(" + result.length + ")" + "Encrypted Data: " + Arrays.toString(result));87 65 return result; 88 66 } catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
Note:
See TracChangeset
for help on using the changeset viewer.