Compare commits

..

No commits in common. "master" and "v1.11.0" have entirely different histories.

20 changed files with 2064 additions and 1515 deletions

1047
LICENSE

File diff suppressed because it is too large Load Diff

3
PATCHNOTES.md Normal file
View File

@ -0,0 +1,3 @@
### Version 1.11.0 / 04.05.2020
CryptoGX was uploaded for the first time on github

View File

@ -1,5 +1,3 @@
**please just use another encryption software which works correctly and has better en-/decoding options**
**_cryptoGX_** - just another en- / decryption software **_cryptoGX_** - just another en- / decryption software
- [Introduction](#introduction) - [Introduction](#introduction)
@ -12,20 +10,16 @@
**cryptoGX** is a java based software for en- / decrypting texts or files and secure delete files. **cryptoGX** is a java based software for en- / decrypting texts or files and secure delete files.
It was designed to be controlled with a GUI, but can also be used from the command line. It was designed to be controlled with a GUI, but can also be used from the command line.
Because the GUI uses javaFX, java version from 1.8.0_40 to 10.* with javaFX support is required. Because the GUI uses javaFX, java version from 1.8.0_40 to 10.* with javaFX support is required (also applies to windows .exe files).
Alternatively you can compile the [source code](#https://github.com/blueShard-dev/cryptoGX/archive/master.zip) with higher
java version and include [javaFX](#https://openjfx.io/) manually
# Downloads # Downloads
### [All releases](#https://github.com/blueShard-dev/cryptoGX/releases/) | 1.11.0 |
|:-------|
| Latest release (1.12.0) | | [Source code](https://github.com/blueShard-dev/cryptoGX/archive/master.zip) |
|:------------------------| | [Executable jar file](https://dl.dropbox.com/s/1px5dotzyop3rpn/cryptoGX.jar?dl=0) |
| [Source code](https://github.com/blueShard-dev/cryptoGX/archive/v1.12.0.zip) | | [Windows portable](https://dl.dropbox.com/s/10jf6cfpnejrvbf/cryptoGX_1.11.0_portable.exe?dl=0) |
| [Executable jar file](https://github.com/blueShard-dev/cryptoGX/releases/download/v1.12.0/cryptoGX.jar) | | [Windows installer](https://dl.dropbox.com/s/lq9kuv4erv39y3n/cryptoGX_1.11.0_win_setup.exe?dl=0) |
| [Windows installer](https://github.com/blueShard-dev/cryptoGX/releases/download/v1.12.0/cryptoGX-1.12.0_win_installer.exe) |
| [Debian installer](https://github.com/blueShard-dev/cryptoGX/releases/download/v1.12.0/cryptogx-1.12.0_debian_installer.deb) |
**NOTE**: If you download one of the windows executables (`.exe`) your antivirus may scan the file(s) **NOTE**: If you download one of the windows executables (`.exe`) your antivirus may scan the file(s)
@ -47,10 +41,10 @@ Usage AES:
encrypt: <cryptoGX jar file> AES <key> <salt> encrypt <path of file to encrypt> <encrypted file dest> encrypt: <cryptoGX jar file> AES <key> <salt> encrypt <path of file to encrypt> <encrypted file dest>
decrypt: <cryptoGX jar file> AES <key> <salt> decrypt <encrypted file path> <decrypted file dest> decrypt: <cryptoGX jar file> AES <key> <salt> decrypt <encrypted file path> <decrypted file dest>
File secure delete: <cryptoGX jar file> delete <iterations> <path of file to delete> //for <iterations> the argument 'default' can be used, which is 5 Secure delete file: <iterations> <path of file to delete>
``` ```
or type `<cryptoGX jar file> help` to get help or type `<cryptoGX jar file> -help` to get help
# License # License
This project is licensed under the Mozilla Public Licence 2.0 - see the [LICENSE](LICENSE) file for more details This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for more details

View File

@ -1,4 +1,4 @@
package org.bytedream.cryptoGX; package org.blueshard.cryptogx;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
@ -16,6 +16,10 @@ import javafx.stage.*;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException; import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException; import javax.crypto.NoSuchPaddingException;
import javax.xml.stream.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*; import java.io.*;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -23,18 +27,16 @@ import java.security.spec.InvalidKeySpecException;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import static org.bytedream.cryptogx.Main.*; import static org.blueshard.cryptogx.Main.*;
/** /**
* <p>Class for the user configuration / settings</p> * <p>Class for the user configuration / settings</p>
*
* @since 1.12.0
*/ */
public class Settings { public class Config {
private static double addSettingsGUIX, addSettingsGUIY; private static double addConfigGUIX, addConfigGUIY;
private static final HashSet<String> protectedSettingsNames = new HashSet<>(Arrays.asList("cryptoGX", "settings")); private static final HashSet<String> protectedConfigNames = new HashSet<>(Arrays.asList("cryptoGX", "config"));
/** /**
* <p>Shows a GUI where the user can save settings, which can load later</p> * <p>Shows a GUI where the user can save settings, which can load later</p>
@ -42,15 +44,13 @@ public class Settings {
* @param rootWindow from which this GUI will get called * @param rootWindow from which this GUI will get called
* @param userSetting * @param userSetting
* @throws IOException * @throws IOException
*
* @since 1.11.0
*/ */
public static void addSettingGUI(Window rootWindow, Map<String, String> userSetting) throws IOException { public static void addSettingGUI(Window rootWindow, Map<String, String> userSetting) throws IOException {
Map<String, String> newSettingItems = new HashMap<>(); Map<String, String> newSettingItems = new HashMap<>();
Stage rootStage = new Stage(); Stage rootStage = new Stage();
rootStage.initOwner(rootWindow); rootStage.initOwner(rootWindow);
Parent addSettingsRoot = FXMLLoader.load(Settings.class.getResource("resources/addSettingsGUI.fxml")); Parent addSettingsRoot = FXMLLoader.load(Config.class.getResource("resources/addSettingsGUI.fxml"));
rootStage.initStyle(StageStyle.UNDECORATED); rootStage.initStyle(StageStyle.UNDECORATED);
rootStage.initModality(Modality.WINDOW_MODAL); rootStage.initModality(Modality.WINDOW_MODAL);
rootStage.setResizable(false); rootStage.setResizable(false);
@ -60,12 +60,12 @@ public class Settings {
rootStage.setScene(scene); rootStage.setScene(scene);
scene.setOnMouseDragged(event -> { scene.setOnMouseDragged(event -> {
rootStage.setX(event.getScreenX() + addSettingsGUIX); rootStage.setX(event.getScreenX() + addConfigGUIX);
rootStage.setY(event.getScreenY() + addSettingsGUIY); rootStage.setY(event.getScreenY() + addConfigGUIY);
}); });
scene.setOnMousePressed(event -> { scene.setOnMousePressed(event -> {
addSettingsGUIX = scene.getX() - event.getSceneX(); addConfigGUIX = scene.getX() - event.getSceneX();
addSettingsGUIY = scene.getY() - event.getSceneY(); addConfigGUIY = scene.getY() - event.getSceneY();
}); });
Thread thread = new Thread(() -> { Thread thread = new Thread(() -> {
@ -78,12 +78,12 @@ public class Settings {
Platform.runLater(() -> { Platform.runLater(() -> {
MenuBar menuBar = (MenuBar) addSettingsRoot.lookup("#menuBar"); MenuBar menuBar = (MenuBar) addSettingsRoot.lookup("#menuBar");
menuBar.setOnMouseDragged(event -> { menuBar.setOnMouseDragged(event -> {
rootStage.setX(event.getScreenX() + addSettingsGUIX); rootStage.setX(event.getScreenX() + addConfigGUIX);
rootStage.setY(event.getScreenY() + addSettingsGUIY); rootStage.setY(event.getScreenY() + addConfigGUIY);
}); });
menuBar.setOnMousePressed(event -> { menuBar.setOnMousePressed(event -> {
addSettingsGUIX = menuBar.getLayoutX() - event.getSceneX(); addConfigGUIX = menuBar.getLayoutX() - event.getSceneX();
addSettingsGUIY = menuBar.getLayoutY() - event.getSceneY(); addConfigGUIY = menuBar.getLayoutY() - event.getSceneY();
}); });
ImageView closeButton = (ImageView) addSettingsRoot.lookup("#closeButton"); ImageView closeButton = (ImageView) addSettingsRoot.lookup("#closeButton");
@ -96,7 +96,7 @@ public class Settings {
TextField textSaltEntry = (TextField) addSettingsRoot.lookup("#textSaltEntry"); TextField textSaltEntry = (TextField) addSettingsRoot.lookup("#textSaltEntry");
textSaltEntry.setText(userSetting.get("textSalt")); textSaltEntry.setText(userSetting.get("textSalt"));
ComboBox textAlgorithmBox = (ComboBox) addSettingsRoot.lookup("#textAlgorithmComboBox"); ComboBox textAlgorithmBox = (ComboBox) addSettingsRoot.lookup("#textAlgorithmComboBox");
textAlgorithmBox.setItems(FXCollections.observableArrayList(Utils.algorithms.keySet())); textAlgorithmBox.setItems(FXCollections.observableArrayList(textAlgorithms));
textAlgorithmBox.setValue(userSetting.get("textAlgorithm")); textAlgorithmBox.setValue(userSetting.get("textAlgorithm"));
TextField fileEnDecryptKeyEntry = (TextField) addSettingsRoot.lookup("#fileEnDecryptKeyEntry"); TextField fileEnDecryptKeyEntry = (TextField) addSettingsRoot.lookup("#fileEnDecryptKeyEntry");
@ -104,7 +104,7 @@ public class Settings {
TextField fileEnDecryptSaltEntry = (TextField) addSettingsRoot.lookup("#fileEnDecryptSaltEntry"); TextField fileEnDecryptSaltEntry = (TextField) addSettingsRoot.lookup("#fileEnDecryptSaltEntry");
fileEnDecryptSaltEntry.setText(userSetting.get("fileEnDecryptSalt")); fileEnDecryptSaltEntry.setText(userSetting.get("fileEnDecryptSalt"));
ComboBox fileEnDecryptAlgorithmBox = (ComboBox) addSettingsRoot.lookup("#fileEnDecryptAlgorithmComboBox"); ComboBox fileEnDecryptAlgorithmBox = (ComboBox) addSettingsRoot.lookup("#fileEnDecryptAlgorithmComboBox");
fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(Utils.algorithms.keySet())); fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(fileEnDecryptAlgorithms));
fileEnDecryptAlgorithmBox.setValue(userSetting.get("fileEnDecryptAlgorithm")); fileEnDecryptAlgorithmBox.setValue(userSetting.get("fileEnDecryptAlgorithm"));
TextField fileDeleteIterationEntry = (TextField) addSettingsRoot.lookup("#fileDeleteIterationsEntry"); TextField fileDeleteIterationEntry = (TextField) addSettingsRoot.lookup("#fileDeleteIterationsEntry");
@ -117,45 +117,35 @@ public class Settings {
TextField fileOutputPathEntry = (TextField) addSettingsRoot.lookup("#fileOutputPathEntry"); TextField fileOutputPathEntry = (TextField) addSettingsRoot.lookup("#fileOutputPathEntry");
fileOutputPathEntry.setText(userSetting.get("fileOutputPath")); fileOutputPathEntry.setText(userSetting.get("fileOutputPath"));
Button fileOutputPathButton = (Button) addSettingsRoot.lookup("#fileOutputPathButton");
fileOutputPathButton.setOnAction(event -> {
DirectoryChooser directoryChooser = new DirectoryChooser();
File directory = directoryChooser.showDialog(rootWindow.getScene().getWindow());
try {
fileOutputPathEntry.setText(directory.getAbsolutePath());
} catch (NullPointerException e) {
e.printStackTrace();
}
});
CheckBox removeFromFileBoxCheckBox = (CheckBox) addSettingsRoot.lookup("#removeFromFileBoxCheckBox"); CheckBox removeFromFileBoxCheckBox = (CheckBox) addSettingsRoot.lookup("#removeFromFileBoxCheckBox");
removeFromFileBoxCheckBox.setSelected(Boolean.parseBoolean(userSetting.get("removeFromFileBox"))); removeFromFileBoxCheckBox.setSelected(Boolean.parseBoolean(userSetting.get("removeFromFileBox")));
CheckBox limitNumberOfThreadsCheckBox = (CheckBox) addSettingsRoot.lookup("#limitNumberOfThreadsCheckBox"); CheckBox limitNumberOfThreadsCheckBox = (CheckBox) addSettingsRoot.lookup("#limitNumberOfThreadsCheckBox");
limitNumberOfThreadsCheckBox.setSelected(Boolean.parseBoolean(userSetting.get("limitNumberOfThreads"))); limitNumberOfThreadsCheckBox.setSelected(Boolean.parseBoolean(userSetting.get("limitNumberOfThreads")));
PasswordField hiddenPasswordEntry = (PasswordField) addSettingsRoot.lookup("#hiddenPasswordEntry"); PasswordField hiddenPasswordEntry = (PasswordField) addSettingsRoot.lookup("#hiddenPasswordEntry");
TextField visiblePasswordEntry = (TextField) addSettingsRoot.lookup("#visiblePasswordEntry"); TextField showedPasswordEntry = (TextField) addSettingsRoot.lookup("#showedPasswordEntry");
CheckBox showPassword = (CheckBox) addSettingsRoot.lookup("#showPassword"); CheckBox showPassword = (CheckBox) addSettingsRoot.lookup("#showPassword");
showPassword.setOnAction(event -> { showPassword.setOnAction(event -> {
if (showPassword.isSelected()) { if (showPassword.isSelected()) {
visiblePasswordEntry.setText(hiddenPasswordEntry.getText()); showedPasswordEntry.setText(hiddenPasswordEntry.getText());
visiblePasswordEntry.setVisible(true); showedPasswordEntry.setVisible(true);
hiddenPasswordEntry.setVisible(false); hiddenPasswordEntry.setVisible(false);
} else { } else {
hiddenPasswordEntry.setText(visiblePasswordEntry.getText()); hiddenPasswordEntry.setText(showedPasswordEntry.getText());
hiddenPasswordEntry.setVisible(true); hiddenPasswordEntry.setVisible(true);
visiblePasswordEntry.setVisible(false); showedPasswordEntry.setVisible(false);
} }
}); });
CheckBox encryptSettings = (CheckBox) addSettingsRoot.lookup("#encryptSettings"); CheckBox encryptSettings = (CheckBox) addSettingsRoot.lookup("#encryptSettings");
encryptSettings.setOnAction(event -> { encryptSettings.setOnAction(event -> {
if (encryptSettings.isSelected()) { if (encryptSettings.isSelected()) {
hiddenPasswordEntry.setDisable(false); hiddenPasswordEntry.setDisable(false);
visiblePasswordEntry.setDisable(false); showedPasswordEntry.setDisable(false);
showPassword.setDisable(false); showPassword.setDisable(false);
} else { } else {
hiddenPasswordEntry.setDisable(true); hiddenPasswordEntry.setDisable(true);
visiblePasswordEntry.setDisable(true); showedPasswordEntry.setDisable(true);
showPassword.setDisable(true); showPassword.setDisable(true);
} }
}); });
@ -163,23 +153,19 @@ public class Settings {
saveButton.setOnAction(event -> { saveButton.setOnAction(event -> {
if (settingsNameEntry.getText().trim().isEmpty()) { if (settingsNameEntry.getText().trim().isEmpty()) {
warningAlert("Add a name for the setting"); warningAlert("Add a name for the setting");
} else if (protectedSettingsNames.contains(settingsNameEntry.getText())) { } else if (protectedConfigNames.contains(settingsNameEntry.getText())) {
warningAlert("Please choose another name for this setting"); warningAlert("Please choose another name for this setting");
} else if (settingsNameEntry.getText().trim().contains(" ")) {
warningAlert("Setting name must not contain free space");
} else if (encryptSettings.isSelected()){ } else if (encryptSettings.isSelected()){
try { try {
EnDecrypt.AES encrypt; EnDecrypt.AES encrypt;
if (!hiddenPasswordEntry.isDisabled() && !hiddenPasswordEntry.getText().trim().isEmpty()) { if (!hiddenPasswordEntry.isDisabled()) {
encrypt = new EnDecrypt.AES(hiddenPasswordEntry.getText(), new byte[16]); encrypt = new EnDecrypt.AES(hiddenPasswordEntry.getText(), new byte[16]);
} else if (!visiblePasswordEntry.getText().trim().isEmpty()) { newSettingItems.put("encryptHash", encrypt.encrypt(hiddenPasswordEntry.getText()));
encrypt = new EnDecrypt.AES(visiblePasswordEntry.getText(), new byte[16]);
} else { } else {
throw new InvalidKeyException("The key must not be empty"); encrypt = new EnDecrypt.AES(showedPasswordEntry.getText(), new byte[16]);
newSettingItems.put("encryptHash", encrypt.encrypt(showedPasswordEntry.getText()));
} }
newSettingItems.put("encrypted", "true");
newSettingItems.put("textKey", encrypt.encrypt(textKeyEntry.getText())); newSettingItems.put("textKey", encrypt.encrypt(textKeyEntry.getText()));
newSettingItems.put("textSalt", encrypt.encrypt(textSaltEntry.getText())); newSettingItems.put("textSalt", encrypt.encrypt(textSaltEntry.getText()));
newSettingItems.put("textAlgorithm", encrypt.encrypt(textAlgorithmBox.getSelectionModel().getSelectedItem().toString())); newSettingItems.put("textAlgorithm", encrypt.encrypt(textAlgorithmBox.getSelectionModel().getSelectedItem().toString()));
@ -194,28 +180,15 @@ public class Settings {
newSettingItems.put("removeFromFileBox", encrypt.encrypt(String.valueOf(removeFromFileBoxCheckBox.isSelected()))); newSettingItems.put("removeFromFileBox", encrypt.encrypt(String.valueOf(removeFromFileBoxCheckBox.isSelected())));
newSettingItems.put("limitNumberOfThreads", encrypt.encrypt(String.valueOf(limitNumberOfThreadsCheckBox.isSelected()))); newSettingItems.put("limitNumberOfThreads", encrypt.encrypt(String.valueOf(limitNumberOfThreadsCheckBox.isSelected())));
if (!config.isFile()) { addSetting(settingsNameEntry.getText(), newSettingItems);
try {
if (!config.createNewFile()) {
warningAlert("Couldn't create config file");
} else {
addSetting(config, settingsNameEntry.getText().trim(), newSettingItems);
}
} catch (IOException e) {
e.printStackTrace();
errorAlert("Couldn't create config file", e.getMessage());
}
} else {
addSetting(config, settingsNameEntry.getText().trim(), newSettingItems);
}
rootStage.close(); rootStage.close();
} catch (InvalidKeyException e) { } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException e) {
warningAlert("The key must not be empty");
} catch (NoSuchPaddingException | NoSuchAlgorithmException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException e) {
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
newSettingItems.put("encryptHash", "");
newSettingItems.put("textKey", textKeyEntry.getText()); newSettingItems.put("textKey", textKeyEntry.getText());
newSettingItems.put("textSalt", textSaltEntry.getText()); newSettingItems.put("textSalt", textSaltEntry.getText());
newSettingItems.put("textAlgorithm", textAlgorithmBox.getSelectionModel().getSelectedItem().toString()); newSettingItems.put("textAlgorithm", textAlgorithmBox.getSelectionModel().getSelectedItem().toString());
@ -230,20 +203,7 @@ public class Settings {
newSettingItems.put("removeFromFileBox", String.valueOf(removeFromFileBoxCheckBox.isSelected())); newSettingItems.put("removeFromFileBox", String.valueOf(removeFromFileBoxCheckBox.isSelected()));
newSettingItems.put("limitNumberOfThreads", String.valueOf(limitNumberOfThreadsCheckBox.isSelected())); newSettingItems.put("limitNumberOfThreads", String.valueOf(limitNumberOfThreadsCheckBox.isSelected()));
if (!config.isFile()) { addSetting(settingsNameEntry.getText(), newSettingItems);
try {
if (!config.createNewFile()) {
warningAlert("Couldn't create config file");
} else {
addSetting(config, settingsNameEntry.getText().trim(), newSettingItems);
}
} catch (IOException e) {
e.printStackTrace();
errorAlert("Couldn't create config file", e.getMessage());
}
} else {
addSetting(config, settingsNameEntry.getText().trim(), newSettingItems);
}
rootStage.close(); rootStage.close();
} }
@ -261,13 +221,11 @@ public class Settings {
* *
* @param rootWindow from which this GUI will get called * @param rootWindow from which this GUI will get called
* @throws IOException * @throws IOException
*
* @since 1.11.0
*/ */
public static void exportSettingsGUI(Window rootWindow) throws IOException { public static void exportSettingsGUI(Window rootWindow) throws IOException {
Stage rootStage = new Stage(); Stage rootStage = new Stage();
rootStage.initOwner(rootWindow); rootStage.initOwner(rootWindow);
Parent exportSettingsRoot = FXMLLoader.load(Settings.class.getResource("resources/exportSettingsGUI.fxml")); Parent exportSettingsRoot = FXMLLoader.load(Config.class.getResource("resources/exportSettingsGUI.fxml"));
rootStage.initStyle(StageStyle.UNDECORATED); rootStage.initStyle(StageStyle.UNDECORATED);
rootStage.initModality(Modality.WINDOW_MODAL); rootStage.initModality(Modality.WINDOW_MODAL);
rootStage.setResizable(false); rootStage.setResizable(false);
@ -277,12 +235,12 @@ public class Settings {
rootStage.setScene(scene); rootStage.setScene(scene);
scene.setOnMouseDragged(event -> { scene.setOnMouseDragged(event -> {
rootStage.setX(event.getScreenX() + addSettingsGUIX); rootStage.setX(event.getScreenX() + addConfigGUIX);
rootStage.setY(event.getScreenY() + addSettingsGUIY); rootStage.setY(event.getScreenY() + addConfigGUIY);
}); });
scene.setOnMousePressed(event -> { scene.setOnMousePressed(event -> {
addSettingsGUIX = scene.getX() - event.getSceneX(); addConfigGUIX = scene.getX() - event.getSceneX();
addSettingsGUIY = scene.getY() - event.getSceneY(); addConfigGUIY = scene.getY() - event.getSceneY();
}); });
Thread thread = new Thread(() -> { Thread thread = new Thread(() -> {
@ -293,18 +251,18 @@ public class Settings {
} }
MenuBar menuBar = (MenuBar) exportSettingsRoot.lookup("#menuBar"); MenuBar menuBar = (MenuBar) exportSettingsRoot.lookup("#menuBar");
menuBar.setOnMouseDragged(event -> { menuBar.setOnMouseDragged(event -> {
rootStage.setX(event.getScreenX() + addSettingsGUIX); rootStage.setX(event.getScreenX() + addConfigGUIX);
rootStage.setY(event.getScreenY() + addSettingsGUIY); rootStage.setY(event.getScreenY() + addConfigGUIY);
}); });
menuBar.setOnMousePressed(event -> { menuBar.setOnMousePressed(event -> {
addSettingsGUIX = menuBar.getLayoutX() - event.getSceneX(); addConfigGUIX = menuBar.getLayoutX() - event.getSceneX();
addSettingsGUIY = menuBar.getLayoutY() - event.getSceneY(); addConfigGUIY = menuBar.getLayoutY() - event.getSceneY();
}); });
ImageView closeButton = (ImageView) exportSettingsRoot.lookup("#closeButton"); ImageView closeButton = (ImageView) exportSettingsRoot.lookup("#closeButton");
closeButton.setOnMouseClicked(event -> rootStage.close()); closeButton.setOnMouseClicked(event -> rootStage.close());
VBox settingsBox = (VBox) exportSettingsRoot.lookup("#settingsBox"); VBox settingsBox = (VBox) exportSettingsRoot.lookup("#settingsBox");
Platform.runLater(() -> readSettings(config).keySet().forEach(s -> { Platform.runLater(() -> readUserSettings().keySet().forEach(s -> {
CheckBox newCheckBox = new CheckBox(); CheckBox newCheckBox = new CheckBox();
newCheckBox.setText(s); newCheckBox.setText(s);
settingsBox.getChildren().add(newCheckBox); settingsBox.getChildren().add(newCheckBox);
@ -315,12 +273,12 @@ public class Settings {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Export settings"); fileChooser.setTitle("Export settings");
fileChooser.setInitialFileName("settings.config"); fileChooser.setInitialFileName("settings.config");
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Config files", "*.config"), fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Config files", "*.config", "*.xml"),
new FileChooser.ExtensionFilter("All files", "*.*")); new FileChooser.ExtensionFilter("All files", "*.*"));
File file = fileChooser.showSaveDialog(exportSettingsRoot.getScene().getWindow()); File file = fileChooser.showSaveDialog(exportSettingsRoot.getScene().getWindow());
if (file != null) { if (file != null) {
TreeMap<String, Map<String, String>> writeInfos = new TreeMap<>(); TreeMap<String, Map<String, String>> writeInfos = new TreeMap<>();
TreeMap<String, Map<String, String>> settings = readSettings(config); TreeMap<String, Map<String, String>> settings = readUserSettings();
for (int i=0; i<settingsBox.getChildren().size(); i++) { for (int i=0; i<settingsBox.getChildren().size(); i++) {
CheckBox checkBox = (CheckBox) settingsBox.getChildren().get(i); CheckBox checkBox = (CheckBox) settingsBox.getChildren().get(i);
if (checkBox.isSelected()) { if (checkBox.isSelected()) {
@ -331,7 +289,7 @@ public class Settings {
if (!file.getAbsolutePath().contains(".")) { if (!file.getAbsolutePath().contains(".")) {
file = new File(file.getAbsolutePath() + ".config"); file = new File(file.getAbsolutePath() + ".config");
} }
writeSettings(file, writeInfos); writeConfig(file, writeInfos);
} }
}); });
}); });
@ -347,32 +305,30 @@ public class Settings {
* @param rootWindow from which this GUI will get called * @param rootWindow from which this GUI will get called
* @return the settings that the user has chosen * @return the settings that the user has chosen
* @throws IOException * @throws IOException
*
* @since 1.11.0
*/ */
public static TreeMap<String, Map<String, String>> loadSettingsGUI(Window rootWindow) throws IOException { public static TreeMap<String, Map<String, String>> loadSettingsGUI(Window rootWindow) throws IOException {
Button[] outerLoadButton = new Button[1]; Button[] outerLoadButton = new Button[1];
HashMap<String, String> setting = new HashMap<>(); HashMap<String, String> setting = new HashMap<>();
TreeMap<String, Map<String, String>> settingItems = readSettings(config); TreeMap<String, Map<String, String>> settingItems = readUserSettings();
TreeMap<String, Map<String, String>> returnItems = new TreeMap<>(); TreeMap<String, Map<String, String>> returnItems = new TreeMap<>();
Stage rootStage = new Stage(); Stage rootStage = new Stage();
rootStage.initOwner(rootWindow); rootStage.initOwner(rootWindow);
AnchorPane loadSettingsRoot = FXMLLoader.load(Settings.class.getResource("resources/loadSettingsGUI.fxml")); AnchorPane loadSettingsRoot = FXMLLoader.load(Config.class.getResource("resources/loadSettingsGUI.fxml"));
rootStage.initStyle(StageStyle.UNDECORATED); rootStage.initStyle(StageStyle.UNDECORATED);
rootStage.initModality(Modality.WINDOW_MODAL); rootStage.initModality(Modality.WINDOW_MODAL);
rootStage.setResizable(false); rootStage.setResizable(false);
rootStage.setTitle("cryptoGX"); rootStage.setTitle("cryptoGX");
rootStage.getIcons().add(new Image(Settings.class.getResource("resources/cryptoGX.png").toExternalForm())); rootStage.getIcons().add(new Image(Config.class.getResource("resources/cryptoGX.png").toExternalForm()));
Scene scene = new Scene(loadSettingsRoot, 242, 235); Scene scene = new Scene(loadSettingsRoot, 242, 235);
scene.setOnMouseDragged(event -> { scene.setOnMouseDragged(event -> {
rootStage.setX(event.getScreenX() + addSettingsGUIX); rootStage.setX(event.getScreenX() + addConfigGUIX);
rootStage.setY(event.getScreenY() + addSettingsGUIY); rootStage.setY(event.getScreenY() + addConfigGUIY);
}); });
scene.setOnMousePressed(event -> { scene.setOnMousePressed(event -> {
addSettingsGUIX = scene.getX() - event.getSceneX(); addConfigGUIX = scene.getX() - event.getSceneX();
addSettingsGUIY = scene.getY() - event.getSceneY(); addConfigGUIY = scene.getY() - event.getSceneY();
}); });
scene.setOnKeyReleased(event -> { scene.setOnKeyReleased(event -> {
@ -390,12 +346,12 @@ public class Settings {
Platform.runLater(() -> { Platform.runLater(() -> {
MenuBar menuBar = (MenuBar) loadSettingsRoot.lookup("#menuBar"); MenuBar menuBar = (MenuBar) loadSettingsRoot.lookup("#menuBar");
menuBar.setOnMouseDragged(event -> { menuBar.setOnMouseDragged(event -> {
rootStage.setX(event.getScreenX() + addSettingsGUIX); rootStage.setX(event.getScreenX() + addConfigGUIX);
rootStage.setY(event.getScreenY() + addSettingsGUIY); rootStage.setY(event.getScreenY() + addConfigGUIY);
}); });
menuBar.setOnMousePressed(event -> { menuBar.setOnMousePressed(event -> {
addSettingsGUIX = menuBar.getLayoutX() - event.getSceneX(); addConfigGUIX = menuBar.getLayoutX() - event.getSceneX();
addSettingsGUIY = menuBar.getLayoutY() - event.getSceneY(); addConfigGUIY = menuBar.getLayoutY() - event.getSceneY();
}); });
ImageView closeButton = (ImageView) loadSettingsRoot.lookup("#closeButton"); ImageView closeButton = (ImageView) loadSettingsRoot.lookup("#closeButton");
@ -404,6 +360,8 @@ public class Settings {
} }
closeButton.setOnMouseClicked(event -> { closeButton.setOnMouseClicked(event -> {
setting.put("encryptHash", configDefaultEncryptHash);
setting.put("textKey", configDefaultTextKey); setting.put("textKey", configDefaultTextKey);
setting.put("textSalt", configDefaultTextSalt); setting.put("textSalt", configDefaultTextSalt);
setting.put("textAlgorithm", configDefaultTextAlgorithm); setting.put("textAlgorithm", configDefaultTextAlgorithm);
@ -442,7 +400,7 @@ public class Settings {
ComboBox settingsBox = (ComboBox) loadSettingsRoot.lookup("#settingsBox"); ComboBox settingsBox = (ComboBox) loadSettingsRoot.lookup("#settingsBox");
settingsBox.setItems(FXCollections.observableArrayList(settingItems.keySet())); settingsBox.setItems(FXCollections.observableArrayList(settingItems.keySet()));
settingsBox.setValue(settingItems.firstKey()); settingsBox.setValue(settingItems.firstKey());
if (!Boolean.parseBoolean(settingItems.firstEntry().getValue().get("encrypted").trim())) { if (settingItems.firstEntry().getValue().get("encryptHash").trim().isEmpty()) {
keyHideEntry.clear(); keyHideEntry.clear();
keyHideEntry.setDisable(true); keyHideEntry.setDisable(true);
keyShowEntry.setDisable(true); keyShowEntry.setDisable(true);
@ -450,7 +408,7 @@ public class Settings {
} }
settingsBox.setOnAction(event -> { settingsBox.setOnAction(event -> {
try { try {
if (!Boolean.parseBoolean(settingItems.get(settingsBox.getSelectionModel().getSelectedItem().toString()).get("encrypted").trim())) { if (settingItems.get(settingsBox.getSelectionModel().getSelectedItem().toString()).get("encryptHash").trim().isEmpty()) {
keyHideEntry.clear(); keyHideEntry.clear();
keyHideEntry.setDisable(true); keyHideEntry.setDisable(true);
keyShowEntry.clear(); keyShowEntry.clear();
@ -473,6 +431,8 @@ public class Settings {
String settingName = settingsBox.getSelectionModel().getSelectedItem().toString(); String settingName = settingsBox.getSelectionModel().getSelectedItem().toString();
Map<String, String> selectedSetting = settingItems.get(settingName); Map<String, String> selectedSetting = settingItems.get(settingName);
if (keyHideEntry.isDisabled() && showPassword.isDisabled() && showPassword.isDisabled()) { if (keyHideEntry.isDisabled() && showPassword.isDisabled() && showPassword.isDisabled()) {
setting.put("encryptHash", "");
setting.put("textKey", selectedSetting.get("textKey")); setting.put("textKey", selectedSetting.get("textKey"));
setting.put("textSalt", selectedSetting.get("textSalt")); setting.put("textSalt", selectedSetting.get("textSalt"));
setting.put("textAlgorithm", selectedSetting.get("textAlgorithm")); setting.put("textAlgorithm", selectedSetting.get("textAlgorithm"));
@ -498,6 +458,11 @@ public class Settings {
decryptSetting = new EnDecrypt.AES(keyShowEntry.getText(), new byte[16]); decryptSetting = new EnDecrypt.AES(keyShowEntry.getText(), new byte[16]);
} }
try { try {
if (keyHideEntry.isVisible() && !decryptSetting.encrypt(keyHideEntry.getText()).equals(settingItems.get(settingsBox.getSelectionModel().getSelectedItem().toString()).get("encryptHash").trim())) {
warningAlert("Wrong key is given");
} else if (keyShowEntry.isVisible() && !decryptSetting.encrypt(keyShowEntry.getText()).equals(settingItems.get(settingsBox.getSelectionModel().getSelectedItem().toString()).get("encryptHash").trim())) {
warningAlert("Wrong key is given");
} else {
Map<String, String> selectedEncryptedSetting = settingItems.get(settingName); Map<String, String> selectedEncryptedSetting = settingItems.get(settingName);
setting.put("textKey", decryptSetting.decrypt(selectedEncryptedSetting.get("textKey"))); setting.put("textKey", decryptSetting.decrypt(selectedEncryptedSetting.get("textKey")));
setting.put("textSalt", decryptSetting.decrypt(selectedEncryptedSetting.get("textSalt"))); setting.put("textSalt", decryptSetting.decrypt(selectedEncryptedSetting.get("textSalt")));
@ -516,11 +481,10 @@ public class Settings {
returnItems.put(settingsBox.getSelectionModel().getSelectedItem().toString(), setting); returnItems.put(settingsBox.getSelectionModel().getSelectedItem().toString(), setting);
rootStage.close(); rootStage.close();
} catch (InvalidKeyException e) { }
warningAlert("Wrong key is given"); } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException e) {
} catch (NoSuchPaddingException | NoSuchAlgorithmException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException e) {
e.printStackTrace(); e.printStackTrace();
warningAlert("Wrong key is given or the config wasn't\nsaved correctly"); warningAlert("Wrong key is given");
} }
} }
}); });
@ -533,7 +497,7 @@ public class Settings {
Alert deleteQuestion = new Alert(Alert.AlertType.CONFIRMATION, "Delete " + settingsBox.getSelectionModel().getSelectedItem().toString() + "?", ButtonType.OK, ButtonType.CANCEL); Alert deleteQuestion = new Alert(Alert.AlertType.CONFIRMATION, "Delete " + settingsBox.getSelectionModel().getSelectedItem().toString() + "?", ButtonType.OK, ButtonType.CANCEL);
deleteQuestion.initStyle(StageStyle.UNDECORATED); deleteQuestion.initStyle(StageStyle.UNDECORATED);
deleteQuestion.setTitle("Confirmation"); deleteQuestion.setTitle("Confirmation");
((Stage) deleteQuestion.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Settings.class.getResource("resources/cryptoGX.png").toExternalForm())); ((Stage) deleteQuestion.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Config.class.getResource("resources/cryptoGX.png").toExternalForm()));
Scene window = deleteQuestion.getDialogPane().getScene(); Scene window = deleteQuestion.getDialogPane().getScene();
@ -548,28 +512,24 @@ public class Settings {
Optional<ButtonType> result = deleteQuestion.showAndWait(); Optional<ButtonType> result = deleteQuestion.showAndWait();
if (result.get() == ButtonType.OK) { if (result.get() == ButtonType.OK) {
if (settingItems.size() - 1 <= 0) { deleteUserSetting(settingsBox.getSelectionModel().getSelectedItem().toString());
settingItems.clear();
settingItems.putAll(readUserSettings());
if (settingItems.size() == 0) {
for (int i=0; i<100; i++) { for (int i=0; i<100; i++) {
if (config.isFile()) { if (config.isFile()) {
try { if (config.delete()) {
SecureDelete.deleteFile(config, 5, new byte[64]);
isConfig = false; isConfig = false;
rootStage.close(); rootStage.close();
break; break;
} catch (IOException e) {
e.printStackTrace();
} }
} }
} }
rootStage.close(); rootStage.close();
} else if (deleteSetting(config, settingsBox.getSelectionModel().getSelectedItem().toString())) { return;
settingItems.remove(settingsBox.getSelectionModel().getSelectedItem().toString()); }
settingsBox.setItems(FXCollections.observableArrayList(settingItems.keySet())); settingsBox.setItems(FXCollections.observableArrayList(settingItems.keySet()));
settingsBox.setValue(settingItems.firstKey()); settingsBox.setValue(settingItems.firstKey());
} else {
warningAlert("Couldn't delete setting '" + settingsBox.getSelectionModel().getSelectedItem().toString() + "'");
}
} }
}); });
}); });
@ -587,152 +547,242 @@ public class Settings {
* <p>Shows a GUI where the user can save the current settings</p> * <p>Shows a GUI where the user can save the current settings</p>
* *
* @param settingName name of the new setting * @param settingName name of the new setting
* @param newSetting is the new setting key value pair * @param userSetting the current settings
*
* @since 1.12.0
*/ */
public static void addSetting(File file, String settingName, Map<String, String> newSetting) { public static void addSetting(String settingName, Map<String, String> userSetting) {
TreeMap<String, Map<String, String>> settings = readSettings(file); TreeMap<String, Map<String, String>> newConfig = new TreeMap<>(readUserSettings());
settings.put(settingName, newSetting); newConfig.put(settingName, userSetting);
writeSettings(file, settings); writeConfig(newConfig);
}
/**
* <p>Shows a GUI where the user can save the current settings</p>
*
* @param settingName name of the new setting
* @param userSetting the current settings
* @param encryptPassword to encrypt the settings
*/
public static void addSetting(String settingName, Map<String, String> userSetting, String encryptPassword) {
TreeMap<String, Map<String, String>> newConfig = new TreeMap<>(readUserSettings());
newConfig.put(settingName, userSetting);
writeConfig(newConfig, Collections.singletonMap(settingName, encryptPassword));
} }
/** /**
* <p>Deletes a saved setting</p> * <p>Deletes a saved setting</p>
* *
* @param settingName of the setting * @param name of the setting
* @return if the setting could be found * @return if the setting could be found
*
* @since 1.12.0
*/ */
public static boolean deleteSetting(File file, String settingName) { public static boolean deleteUserSetting(String name) {
StringBuilder newConfig = new StringBuilder(); TreeMap<String, Map<String, String>> newSetting = new TreeMap<>();
boolean delete = false; TreeMap<String, Map<String, String>> oldSetting = readUserSettings();
boolean found = false; boolean found = false;
try { for (Map.Entry<String, Map<String, String>> entry: oldSetting.entrySet()) {
BufferedReader configReader = new BufferedReader(new FileReader(file)); if (!entry.getKey().equals(name)) {
newSetting.put(entry.getKey(), entry.getValue());
String line;
while ((line = configReader.readLine()) != null) {
line = line.trim();
if (line.startsWith("[") && line.endsWith("]")) {
if (line.replace("[", "").replace("]", "").split(" ")[0].equals(settingName)) {
delete = true;
found = true;
} else if (delete) {
delete = false;
newConfig.append(line).append("\n");
} else { } else {
newConfig.append(line).append("\n"); found = true;
}
} else if (!delete) {
newConfig.append(line).append("\n");
} }
} }
writeConfig(newSetting);
configReader.close();
BufferedWriter configFile = new BufferedWriter(new FileWriter(file));
configFile.write(newConfig.toString());
configFile.newLine();
configFile.close();
} catch (IOException e) {
e.printStackTrace();
}
return found; return found;
} }
public static TreeMap<String, Map<String, String>> readUserSettings() {
return readUserSettings(config);
}
/** /**
* <p>Reads all settings saved in a file</> * @see Config#readUserSettings(String)
*
* @param file from which the settings should be read from
* @return the settings
*
* @since 1.12.0
*/ */
public static TreeMap<String, Map<String, String>> readSettings(File file) { public static TreeMap<String, Map<String, String>> readUserSettings(File file) {
TreeMap<String, Map<String, String>> returnMap = new TreeMap<>(); TreeMap<String, Map<String, String>> rootInfos = new TreeMap<>();
String settingName = null;
Map<String, String> settingValues = new HashMap<>();
try { try {
BufferedReader configReader = new BufferedReader(new FileReader(file)); XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
XMLStreamReader xmlStreamReader;
String line;
while ((line = configReader.readLine()) != null) {
if (line.isEmpty()) {
continue;
} else if (line.startsWith("[") && line.endsWith("]")) {
if (settingName != null) {
returnMap.put(settingName, settingValues);
settingValues = new HashMap<>();
}
String[] newSetting = line.replace("[", "").replace("]", "").split(" ");
settingName = newSetting[0].trim();
String[] encoded = newSetting[1].split("=");
settingValues.put("encrypted", encoded[1]);
} else {
String[] keyValue = line.split("=");
try { try {
settingValues.put(keyValue[0], keyValue[1]); xmlStreamReader = xmlInputFactory.createXMLStreamReader(new FileInputStream(file));
} catch (IndexOutOfBoundsException e) {
settingValues.put(keyValue[0], "");
}
}
}
if (settingName != null) {
returnMap.put(settingName, settingValues);
}
configReader.close();
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); return rootInfos;
warningAlert("Couldn't find file '" + file.getAbsolutePath() + "'"); // this should never raise
} catch (IOException e) {
e.printStackTrace();
errorAlert("An IO Exception occurred", e.getMessage());
} }
return returnMap; HashMap<String, String> infos = new HashMap<>();
String infoName = null;
StringBuilder infoCharacters = new StringBuilder();
String rootName = null;
while (xmlStreamReader.hasNext()) {
int eventType = xmlStreamReader.next();
switch (eventType) {
case XMLStreamReader.START_ELEMENT:
String startTag = xmlStreamReader.getLocalName().trim();
if (startTag != null) {
if (protectedConfigNames.contains(startTag)) {
continue;
} else if (rootName == null) {
rootName = startTag;
} else {
infoName = startTag;
}
}
break;
case XMLStreamReader.CHARACTERS:
if (infoName != null) {
if (!xmlStreamReader.getText().trim().equals("")) {
infoCharacters.append(xmlStreamReader.getText());
}
}
break;
case XMLStreamReader.END_ELEMENT:
String endTag = xmlStreamReader.getLocalName().trim();
if (endTag != null) {
if (protectedConfigNames.contains(endTag)) {
continue;
} else if (endTag.equals(rootName)) {
rootInfos.put(rootName, infos);
rootName = null;
infos = new HashMap<>();
infoCharacters = new StringBuilder();
} else {
infos.put(infoName, infoCharacters.toString());
infoName = null;
infoCharacters = new StringBuilder();
}
}
break;
}
}
xmlStreamReader.close();
} catch (XMLStreamException e) {
e.printStackTrace();
}
System.out.println(rootInfos);
return rootInfos;
}
/**
* <p>Shows a GUI where the user can choose and load saved settings </p>
*
* @param filename of the file with the settings
* @return the setting that the user has chosen
*/
public static TreeMap<String, Map<String, String>> readUserSettings(String filename) {
return readUserSettings(new File(filename));
}
/**
* <p>Writes settings (could be more than one) to the pre-defined config file</p>
*
* @see Config#writeConfig(File, TreeMap, Map)
*/
public static void writeConfig(TreeMap<String, Map<String, String>> userSettings) {
writeConfig(config, userSettings, null);
}
/**
* <p>Writes settings (could be more than one) to the pre-defined config file</p>
*
* @see Config#writeConfig(File, TreeMap, Map)
*/
public static void writeConfig(TreeMap<String, Map<String, String>> userSettings, Map<String, String> encryptedSettings) {
writeConfig(config, userSettings, encryptedSettings);
}
/**
* <p>Writes settings (could be more than one) to the pre-defined config file</p>
*
* @see Config#writeConfig(String, TreeMap, Map)
*/
public static void writeConfig(String filename, TreeMap<String, Map<String, String>> userSettings) {
writeConfig(filename, userSettings, null);
}
/**
* <p>Writes settings (could be more than one) to the pre-defined config file</p>
*
* @see Config#writeConfig(File, TreeMap, Map)
*/
public static void writeConfig(File file, TreeMap<String, Map<String, String>> userSettings) {
writeConfig(file, userSettings, null);
}
/**
* <p>Writes settings (could be more than one) to a file</p>
*
* @see Config#writeConfig(String, TreeMap, Map)
*/
public static void writeConfig(String filename, TreeMap<String, Map<String, String>> userSettings, Map<String, String> encryptedSettings) {
writeConfig(new File(filename), userSettings, encryptedSettings);
} }
/** /**
* <p>Writes settings (could be more than one) to a file</p> * <p>Writes settings (could be more than one) to a file</p>
* *
* @param file where the settings should be written in * @param file where the settings should be written in
* @param settings of the user * @param userSettings of the user
* * @param encryptedSettings says which settings from {@param userSettings} should be encrypted with a password
* @since 1.12.0
*/ */
public static void writeSettings(File file, TreeMap<String, Map<String, String>> settings) { public static void writeConfig(File file, TreeMap<String, Map<String, String>> userSettings, Map<String, String> encryptedSettings) {
EnDecrypt.AES encryptSetting;
StringWriter stringWriter = new StringWriter();
if (encryptedSettings == null) {
encryptedSettings = new HashMap<>();
}
try { try {
BufferedWriter configWriter = new BufferedWriter(new FileWriter(file)); XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(stringWriter);
for (Map.Entry<String, Map<String, String>> settingElement: settings.entrySet()) { xmlStreamWriter.writeStartDocument();
configWriter.write("[" + settingElement.getKey() + " encrypted=" + Boolean.parseBoolean(settingElement.getValue().get("encrypted")) + "]"); xmlStreamWriter.writeStartElement("cryptoGX");
configWriter.newLine(); for (Map.Entry<String, Map<String, String>> settingElement: userSettings.entrySet()) {
xmlStreamWriter.writeStartElement(settingElement.getKey());
if (encryptedSettings.containsKey(settingElement.getKey())) {
encryptSetting = new EnDecrypt.AES(settingElement.getKey(), new byte[16]);
for (Map.Entry<String, String> entry: settingElement.getValue().entrySet()) { for (Map.Entry<String, String> entry: settingElement.getValue().entrySet()) {
String key = entry.getKey(); xmlStreamWriter.writeStartElement(entry.getKey());
if (!key.equals("encrypted")) { xmlStreamWriter.writeCharacters(encryptSetting.encrypt(entry.getValue()));
configWriter.write(entry.getKey() + "=" + entry.getValue()); xmlStreamWriter.writeEndElement();
configWriter.newLine(); }
} else {
for (Map.Entry<String, String> entry: settingElement.getValue().entrySet()) {
xmlStreamWriter.writeStartElement(entry.getKey());
xmlStreamWriter.writeCharacters(entry.getValue());
xmlStreamWriter.writeEndElement();
} }
} }
xmlStreamWriter.writeEndElement();
} }
configWriter.newLine(); xmlStreamWriter.writeEndElement();
xmlStreamWriter.writeEndDocument();
configWriter.close(); //prettify
} catch (IOException e) {
Source xmlInput = new StreamSource(new StringReader(stringWriter.toString()));
StringWriter prettifyStringWriter = new StringWriter();
StreamResult xmlOutput = new StreamResult(prettifyStringWriter);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 2);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(xmlInput, xmlOutput);
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
for (String s: prettifyStringWriter.getBuffer().toString().split(System.lineSeparator())) {
bufferedWriter.write(s);
bufferedWriter.newLine();
}
bufferedWriter.close();
} catch (XMLStreamException | IOException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException | TransformerException e) {
e.printStackTrace(); e.printStackTrace();
errorAlert("An error occurred while saving the settings", e.getMessage());
} }
} }

View File

@ -1,4 +1,4 @@
package org.bytedream.cryptogx; package org.blueshard.cryptogx;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
@ -35,10 +35,6 @@ import java.awt.image.BufferedImage;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -47,8 +43,8 @@ import java.util.*;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import static org.bytedream.cryptogx.Settings.*; import static org.blueshard.cryptogx.Config.*;
import static org.bytedream.cryptogx.Main.*; import static org.blueshard.cryptogx.Main.*;
public class Controller implements Initializable { public class Controller implements Initializable {
@ -58,33 +54,35 @@ public class Controller implements Initializable {
private boolean textLoading = false; private boolean textLoading = false;
private boolean fileEnDecryptLoading = false; private boolean fileEnDecryptLoading = false;
private boolean fileDeleteLoading = false; private boolean fileDeleteLoading = false;
private final AtomicInteger textThreads = new AtomicInteger(0); private AtomicInteger textThreads = new AtomicInteger(0);
private final AtomicInteger totalThreads = new AtomicInteger(0); private AtomicInteger totalThreads = new AtomicInteger(0);
private final int tooltipShow = 15; private int tooltipShow = 15;
private final int DATAFILEURL = 2; private final int DATAFILEURL = 2;
private final int FILEFILEURL = 1; private final int FILEFILEURL = 1;
private final int NONSPECIFICFILEURL = 0; private final int NONSPECIFICFILEURL = 0;
private final byte[] buffer = new byte[64]; private final int IMAGE = 78345;
private final int FILE = 23902;
private final int UNKNOWN = 12345;
private final KeyCombination paste = new KeyCodeCombination(KeyCode.V, KeyCombination.CONTROL_DOWN); private final KeyCombination paste = new KeyCodeCombination(KeyCode.V, KeyCombination.CONTROL_DOWN);
private final Image loadingImage = new Image(getClass().getResource("resources/loading.gif").toExternalForm()); private final Image loadingImage = new Image(getClass().getResource("resources/loading.gif").toExternalForm());
private HashMap<String, String> currentConfigSettings = new HashMap<>(); private HashMap<String, String> currentConfigSettings = new HashMap<>();
private final HashMap<Label, ArrayList<File>> enDecryptInputOutputFiles = new HashMap<>(); private HashMap<Label, ArrayList<File>> enDecryptInputOutputFiles = new HashMap<>();
private final HashMap<Label, ArrayList<Object>> enDecryptInputOutputInternetFiles = new HashMap<>(); private HashMap<Label, ArrayList<Object>> enDecryptInputOutputInternetFiles = new HashMap<>();
private final HashMap<Label, BufferedImage> enDecryptInputOutputClipboardImages = new HashMap<>(); private HashMap<Label, BufferedImage> enDecryptInputOutputClipboardImages = new HashMap<>();
private final HashMap<Label, File> deleteInputFiles = new HashMap<>(); private HashMap<Label, File> deleteInputFiles = new HashMap<>();
private final List<Thread> fileEnDecryptThreads = Collections.synchronizedList(new ArrayList<>()); private List<Thread> fileEnDecryptThreads = Collections.synchronizedList(new ArrayList<>());
private final List<Thread> fileDeleteThreads = Collections.synchronizedList(new ArrayList<>()); private List<Thread> fileDeleteThreads = Collections.synchronizedList(new ArrayList<>());
private final ContextMenu fileEnDecryptInputContextMenu = new ContextMenu(); private ContextMenu fileEnDecryptInputContextMenu = new ContextMenu();
private final ContextMenu fileDeleteInputContextMenu = new ContextMenu(); private ContextMenu fileDeleteInputContextMenu = new ContextMenu();
private Label choosedLabel = null; private Label choosedLabel = null;
private String choosedLabelType = null; private String choosedLabelType = null;
private final MenuItem fileOutputFileChangeDest = new MenuItem("Change output file"); private MenuItem fileOutputFileChangeDest = new MenuItem("Change output file");
private final MenuItem getChoosedLabelInputFileFolder = new MenuItem("Open source directory"); private MenuItem getChoosedLabelInputFileFolder = new MenuItem("Open source directory");
private final MenuItem getChoosedLabelOutputFileFolder = new MenuItem("Open source directory"); private MenuItem getChoosedLabelOutputFileFolder = new MenuItem("Open source directory");
private final Tooltip tooltip = new Tooltip(); private Tooltip tooltip = new Tooltip();
public AnchorPane rootWindow; public AnchorPane rootWindow;
@ -103,7 +101,6 @@ public class Controller implements Initializable {
public ImageView fileDeleteLoadingImage; public ImageView fileDeleteLoadingImage;
public Menu settingsMenu; public Menu settingsMenu;
public Menu helpMenu;
public MenuBar menubar; public MenuBar menubar;
@ -197,13 +194,11 @@ public class Controller implements Initializable {
tooltip.hide(); tooltip.hide();
} }
//-----menu / close bar-----// //-----root-----//
/** /**
* <p>Closed the application. * <p>Closed the application.
* Get called if red close button is pressed</p> * Get called if red close button is pressed</p>
*
* @since 1.0.0
*/ */
public void closeApplication() { public void closeApplication() {
Stage rootStage = (Stage) rootWindow.getScene().getWindow(); Stage rootStage = (Stage) rootWindow.getScene().getWindow();
@ -214,8 +209,6 @@ public class Controller implements Initializable {
/** /**
* <p>Hides the application. * <p>Hides the application.
* Get called if the green minimize button is pressed</p> * Get called if the green minimize button is pressed</p>
*
* @since 1.0.0
*/ */
public void minimizeApplication() { public void minimizeApplication() {
Stage rootStage = (Stage) rootWindow.getScene().getWindow(); Stage rootStage = (Stage) rootWindow.getScene().getWindow();
@ -227,8 +220,6 @@ public class Controller implements Initializable {
/** /**
* <p>Encrypt text in {@link Controller#textDecryptedEntry}. * <p>Encrypt text in {@link Controller#textDecryptedEntry}.
* Get called if the text 'Encrypt' button is pressed</p> * Get called if the text 'Encrypt' button is pressed</p>
*
* @since 1.0.0
*/ */
public void textEncryptButton() { public void textEncryptButton() {
final byte[] salt; final byte[] salt;
@ -252,11 +243,12 @@ public class Controller implements Initializable {
} }
} }
totalThreads.getAndIncrement(); totalThreads.getAndIncrement();
String textAlgorithm = textAlgorithmBox.getSelectionModel().getSelectedItem(); EnDecrypt.AES encrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt);
EnDecrypt.AES encrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt, Integer.parseInt(textAlgorithm.substring(textAlgorithm.indexOf('-') + 1)));
try { try {
String encryptedText = encrypt.encrypt(textDecryptedEntry.getText()); String encryptedText = encrypt.encrypt(textDecryptedEntry.getText());
Platform.runLater(() -> textEncryptedEntry.setText(encryptedText)); Platform.runLater(() -> {
textEncryptedEntry.setText(encryptedText);
});
} catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException | BadPaddingException e) { } catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException | BadPaddingException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IllegalArgumentException | IllegalBlockSizeException e) { } catch (IllegalArgumentException | IllegalBlockSizeException e) {
@ -278,8 +270,6 @@ public class Controller implements Initializable {
/** /**
* <p>Decrypt text in {@link Controller#textEncryptedEntry}. * <p>Decrypt text in {@link Controller#textEncryptedEntry}.
* Get called if the text 'Decrypt' button is pressed</p> * Get called if the text 'Decrypt' button is pressed</p>
*
* @since 1.0.0
*/ */
public void textDecryptButton() { public void textDecryptButton() {
final byte[] salt; final byte[] salt;
@ -303,11 +293,12 @@ public class Controller implements Initializable {
} }
} }
totalThreads.getAndIncrement(); totalThreads.getAndIncrement();
String textAlgorithm = textAlgorithmBox.getSelectionModel().getSelectedItem(); EnDecrypt.AES decrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt);
EnDecrypt.AES decrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt, Integer.parseInt(textAlgorithm.substring(textAlgorithm.indexOf('-') + 1)));
try { try {
String DecryptedText = decrypt.decrypt(textEncryptedEntry.getText()); String DecryptedText = decrypt.decrypt(textEncryptedEntry.getText());
Platform.runLater(() -> textDecryptedEntry.setText(DecryptedText)); Platform.runLater(() -> {
textDecryptedEntry.setText(DecryptedText);
});
} catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) { } catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) {
e.printStackTrace(); e.printStackTrace();
} catch (BadPaddingException e) { } catch (BadPaddingException e) {
@ -344,8 +335,6 @@ public class Controller implements Initializable {
* <p>Synchronized method to get the number of threads which en- / decrypt files</p> * <p>Synchronized method to get the number of threads which en- / decrypt files</p>
* *
* @return number of en- / decryption threads * @return number of en- / decryption threads
*
* @since 1.2.0
*/ */
private synchronized int getFileEnDecryptThreadsSize() { private synchronized int getFileEnDecryptThreadsSize() {
return fileEnDecryptThreads.size(); return fileEnDecryptThreads.size();
@ -355,8 +344,6 @@ public class Controller implements Initializable {
* <p>Synchronized method to add a thread to the file en- / decryption list of current running file en- / decryption threads</p> * <p>Synchronized method to add a thread to the file en- / decryption list of current running file en- / decryption threads</p>
* *
* @param thread that should be added * @param thread that should be added
*
* @since 1.2.0
*/ */
private synchronized void addFileEnDecryptThread(Thread thread) { private synchronized void addFileEnDecryptThread(Thread thread) {
fileEnDecryptThreads.add(thread); fileEnDecryptThreads.add(thread);
@ -366,8 +353,6 @@ public class Controller implements Initializable {
* <p>Synchronized method to remove a thread from the file en- / decryption list of current running file en- / decryption threads</p> * <p>Synchronized method to remove a thread from the file en- / decryption list of current running file en- / decryption threads</p>
* *
* @param thread that should be removed * @param thread that should be removed
*
* @since 1.2.0
*/ */
private synchronized void removeFileEnDecryptThread(Thread thread) { private synchronized void removeFileEnDecryptThread(Thread thread) {
fileEnDecryptThreads.remove(thread); fileEnDecryptThreads.remove(thread);
@ -377,8 +362,6 @@ public class Controller implements Initializable {
* <p>Adds a file for en- / decryption</p> * <p>Adds a file for en- / decryption</p>
* *
* @param file that should be added * @param file that should be added
*
* @since 1.0.0
*/ */
private void fileEnDecryptAddFile(File file) { private void fileEnDecryptAddFile(File file) {
for (Label l: enDecryptInputOutputFiles.keySet()) { for (Label l: enDecryptInputOutputFiles.keySet()) {
@ -401,29 +384,45 @@ public class Controller implements Initializable {
File encryptFile; File encryptFile;
File decryptFile; File decryptFile;
String fileOutputPath = file.getParent() + "/";;
String fileEnding;
ArrayList<File> inputOutputList = new ArrayList<>(); ArrayList<File> inputOutputList = new ArrayList<>();
if (!currentConfigSettings.get("fileOutputPath").trim().isEmpty()) { if (currentConfigSettings.get("fileOutputPath").trim().isEmpty()) {
fileOutputPath = currentConfigSettings.get("fileOutputPath").trim() + "/"; encryptFile = new File(fileAbsolutePath + ".cryptoGX");
while (encryptFile.isFile()) {
encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX");
}
if (fileAbsolutePath.endsWith(".cryptoGX")) {
decryptFile = new File(fileAbsolutePath.substring(0, fileAbsolutePath.length() - 9));
if (decryptFile.isFile()) {
while (decryptFile.isFile()) {
decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
}
} }
if (file.isFile()) {
fileEnding = ".cryptoGX";
} else { } else {
fileEnding = "_cryptoGX"; decryptFile = new File(fileAbsolutePath + ".cryptoGX");
while (decryptFile.isFile()) {
decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
} }
encryptFile = new File(fileOutputPath + fileName + fileEnding);
while (encryptFile.exists()) {
encryptFile = new File(encryptFile.getAbsolutePath() + fileEnding);
} }
if (fileAbsolutePath.endsWith(".cryptoGX") || fileAbsolutePath.endsWith("_cryptoGX")) {
decryptFile = new File(fileOutputPath + fileName.substring(0, fileName.length() - 9));
} else { } else {
decryptFile = new File(fileOutputPath + fileName + fileEnding); encryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + fileName + ".cryptoGX");
while (encryptFile.isFile()) {
encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX");
} }
while (decryptFile.exists()) { if (fileAbsolutePath.endsWith(".cryptoGX")) {
decryptFile = new File(decryptFile.getAbsolutePath() + fileEnding); decryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + fileName.substring(0, fileAbsolutePath.length() - 9));
if (decryptFile.isFile()) {
while (decryptFile.isFile()) {
decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
} }
}
} else {
decryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + fileName + ".cryptoGX");
while (decryptFile.isFile()) {
decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
}
}
}
System.out.println(encryptFile.getAbsolutePath() + ";" + decryptFile.getAbsolutePath());
inputOutputList.add(0, encryptFile); inputOutputList.add(0, encryptFile);
inputOutputList.add(1, decryptFile); inputOutputList.add(1, decryptFile);
fileEnDecryptInputFiles.getChildren().add(newLabel); fileEnDecryptInputFiles.getChildren().add(newLabel);
@ -436,22 +435,16 @@ public class Controller implements Initializable {
* @param url of the file * @param url of the file
* @param fileType of the file * @param fileType of the file
* @throws URISyntaxException * @throws URISyntaxException
*
* @since 1.5.0
*/ */
private void fileEnDecryptAddInternetFile(String url, int fileType) throws URISyntaxException { private void fileEnDecryptAddInternetFile(String url, int fileType) throws URISyntaxException {
String filename; String filename;
switch (fileType) { if (fileType == FILEFILEURL) {
case FILEFILEURL:
filename = url.substring(url.lastIndexOf("/") + 1); filename = url.substring(url.lastIndexOf("/") + 1);
break; } else if (fileType == DATAFILEURL) {
case DATAFILEURL:
filename = url.substring(5, url.indexOf("/")) + "." + url.substring(url.indexOf("/") + 1, url.indexOf(";")); filename = url.substring(5, url.indexOf("/")) + "." + url.substring(url.indexOf("/") + 1, url.indexOf(";"));
break; } else if (fileType == NONSPECIFICFILEURL) {
case NONSPECIFICFILEURL:
filename = "unknown" + System.nanoTime(); filename = "unknown" + System.nanoTime();
break; } else {
default:
warningAlert("Cannot read given url '" + url + "'"); warningAlert("Cannot read given url '" + url + "'");
return; return;
} }
@ -517,8 +510,6 @@ public class Controller implements Initializable {
* *
* @param image that should be added * @param image that should be added
* @throws URISyntaxException * @throws URISyntaxException
*
* @since 1.7.0
*/ */
private void fileEnDecryptAddClipboardImage(BufferedImage image) throws URISyntaxException { private void fileEnDecryptAddClipboardImage(BufferedImage image) throws URISyntaxException {
String filename = "clipboardImage" + System.nanoTime() + ".png"; String filename = "clipboardImage" + System.nanoTime() + ".png";
@ -570,8 +561,6 @@ public class Controller implements Initializable {
* @param label * @param label
* @param encryptOutputFile is the filename of the file it gets encrypted * @param encryptOutputFile is the filename of the file it gets encrypted
* @param decryptOutputFile is the filename of the file it gets decrypted * @param decryptOutputFile is the filename of the file it gets decrypted
*
* @since 1.2.0
*/ */
private void fileOutputFilesChangeText(Label label, String encryptOutputFile, String decryptOutputFile) { private void fileOutputFilesChangeText(Label label, String encryptOutputFile, String decryptOutputFile) {
File encryptFile; File encryptFile;
@ -606,9 +595,17 @@ public class Controller implements Initializable {
* <p>Deletes an entry for en- / decryption. * <p>Deletes an entry for en- / decryption.
* Get called if the user presses 'del' or delete the entry in the en- / decryption box via the right click tooltip</p> * Get called if the user presses 'del' or delete the entry in the en- / decryption box via the right click tooltip</p>
* *
* @param label that should be deleted * @see Controller#fileEnDecryptDeleteEntry(Label)
*/
private void fileEnDecryptDeleteEntry() {
fileEnDecryptDeleteEntry(choosedLabel);
}
/**
* <p>Deletes an entry for en- / decryption.
* Get called if the user presses 'del' or delete the entry in the en- / decryption box via the right click tooltip</p>
* *
* @since 1.2.0 * @param label that should be deleted
*/ */
private void fileEnDecryptDeleteEntry(Label label) { private void fileEnDecryptDeleteEntry(Label label) {
enDecryptInputOutputFiles.remove(label); enDecryptInputOutputFiles.remove(label);
@ -655,8 +652,6 @@ public class Controller implements Initializable {
* Get called if the user click an non-highlighted item in the en- / decryption box</p> * Get called if the user click an non-highlighted item in the en- / decryption box</p>
* *
* @param changeLabel is the label that the user has clicked * @param changeLabel is the label that the user has clicked
*
* @since 1.0.0
*/ */
private void fileEnDecryptSelected(Label changeLabel) { private void fileEnDecryptSelected(Label changeLabel) {
if (changeLabel != null) { if (changeLabel != null) {
@ -681,16 +676,14 @@ public class Controller implements Initializable {
/** /**
* <p>Opens a file chooser GUI where the user can select the files that should be en- / decrypted. * <p>Opens a file chooser GUI where the user can select the files that should be en- / decrypted.
* Get called if the 'Choose files...' in the file en- / decrypt section button is pressed</p> * Get called if the 'Choose files...' in the file en- / decrypt section button is pressed</p>
*
* @since 1.12.0
*/ */
public void fileEnDecryptChooseFiles() { public void fileEnDecryptChoose() {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Choose files"); fileChooser.setTitle("Choose files");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*")); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*"));
List<File> files = fileChooser.showOpenMultipleDialog(rootWindow.getScene().getWindow()); List<File> files = fileChooser.showOpenMultipleDialog(rootWindow.getScene().getWindow());
try { try {
if (files.size() > 0) { if (files.size() >= 1) {
files.forEach(this::fileEnDecryptAddFile); files.forEach(this::fileEnDecryptAddFile);
} }
} catch (NullPointerException e) { } catch (NullPointerException e) {
@ -698,35 +691,20 @@ public class Controller implements Initializable {
} }
} }
/**
* <p>Opens a directory chooser GUI where the user can select the directories that should be en- / decrypted.
* Get called if the 'directories...' in the file en- / decrypt section button is pressed</p>
*
* @since 1.12.0
*/
public void fileEnDecryptChooseDirectories() {
DirectoryChooser directoryChooser = new DirectoryChooser();
directoryChooser.setTitle("Choose directories");
File file = directoryChooser.showDialog(rootWindow.getScene().getWindow());
try {
fileEnDecryptAddFile(file);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
/** /**
* <p>Get called if user drags a (normal or internet) file over the en- / decrypt file box</p> * <p>Get called if user drags a (normal or internet) file over the en- / decrypt file box</p>
* *
* @param event source * @param event source
*
* @since 1.2.0
*/ */
public void onFileEnDecryptDragOver(DragEvent event) { public void onFileEnDecryptDragOver(DragEvent event) {
Dragboard dragboard = event.getDragboard(); Dragboard dragboard = event.getDragboard();
if (event.getGestureSource() != fileEnDecryptInputFiles) { if (event.getGestureSource() != fileEnDecryptInputFiles) {
if (dragboard.hasFiles()) { if (dragboard.hasFiles()) {
if (dragboard.getFiles().size() == 1 && dragboard.getFiles().get(0).isDirectory()) {
return;
} else {
event.acceptTransferModes(TransferMode.COPY_OR_MOVE); event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
} else if (dragboard.hasUrl()) { } else if (dragboard.hasUrl()) {
String url = dragboard.getUrl(); String url = dragboard.getUrl();
String urlFilename = dragboard.getUrl().split("/")[dragboard.getUrl().split("/").length - 1]; String urlFilename = dragboard.getUrl().split("/")[dragboard.getUrl().split("/").length - 1];
@ -739,7 +717,7 @@ public class Controller implements Initializable {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} else if (urlFilename.contains(".") && Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) { } else if (urlFilename.contains(".") && !Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) {
try { try {
new URL(url); new URL(url);
event.acceptTransferModes(TransferMode.COPY_OR_MOVE); event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
@ -759,19 +737,21 @@ public class Controller implements Initializable {
* *
* @param event source * @param event source
* @throws URISyntaxException * @throws URISyntaxException
*
* @since 1.2.0
*/ */
public void onFileEnDecryptDragNDrop(DragEvent event) throws URISyntaxException { public void onFileEnDecryptDragNDrop(DragEvent event) throws URISyntaxException {
Dragboard dragboard = event.getDragboard(); Dragboard dragboard = event.getDragboard();
if (dragboard.hasFiles()) { if (dragboard.hasFiles()) {
dragboard.getFiles().forEach(this::fileEnDecryptAddFile); dragboard.getFiles().forEach(file -> {
if (file.isFile()) {
fileEnDecryptAddFile(file);
}
});
} else if (dragboard.hasUrl()) { } else if (dragboard.hasUrl()) {
String url = dragboard.getUrl(); String url = dragboard.getUrl();
String urlFilename = dragboard.getUrl().split("/")[dragboard.getUrl().split("/").length - 1]; String urlFilename = dragboard.getUrl().split("/")[dragboard.getUrl().split("/").length - 1];
if (url.startsWith("data:")) { if (url.startsWith("data:")) {
fileEnDecryptAddInternetFile(url, DATAFILEURL); fileEnDecryptAddInternetFile(url, DATAFILEURL);
} else if (urlFilename.contains(".") && Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) { } else if (urlFilename.contains(".") && !Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) {
fileEnDecryptAddInternetFile(url, FILEFILEURL); fileEnDecryptAddInternetFile(url, FILEFILEURL);
} else { } else {
fileEnDecryptAddInternetFile(url, NONSPECIFICFILEURL); fileEnDecryptAddInternetFile(url, NONSPECIFICFILEURL);
@ -785,8 +765,6 @@ public class Controller implements Initializable {
* *
* @param event source * @param event source
* @throws URISyntaxException * @throws URISyntaxException
*
* @since 1.7.0
*/ */
public void onFileEnDecryptPaste(KeyEvent event) throws URISyntaxException { public void onFileEnDecryptPaste(KeyEvent event) throws URISyntaxException {
if (paste.match(event)) { if (paste.match(event)) {
@ -812,8 +790,6 @@ public class Controller implements Initializable {
/** /**
* <p>Encrypt all files given files. * <p>Encrypt all files given files.
* Get called if file 'Encrypt' button is pressed</p> * Get called if file 'Encrypt' button is pressed</p>
*
* @since 1.0.0
*/ */
public void fileEncryptButton() { public void fileEncryptButton() {
final byte[] salt; final byte[] salt;
@ -840,24 +816,27 @@ public class Controller implements Initializable {
totalThreads.getAndIncrement(); totalThreads.getAndIncrement();
Label inputFileLabel = entry.getKey(); Label inputFileLabel = entry.getKey();
ArrayList<File> outputFileList = entry.getValue(); ArrayList<File> outputFileList = entry.getValue();
String fileEnDecryptAlgorithm = fileEnDecryptAlgorithmBox.getSelectionModel().getSelectedItem(); EnDecrypt.AES fileEncrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt);
EnDecrypt.AES fileEncrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt, Integer.parseInt(fileEnDecryptAlgorithm.substring(fileEnDecryptAlgorithm.indexOf('-') + 1)));
if (enDecryptInputOutputInternetFiles.containsKey(inputFileLabel)) { if (enDecryptInputOutputInternetFiles.containsKey(inputFileLabel)) {
ArrayList<Object> fileSpecs = enDecryptInputOutputInternetFiles.get(inputFileLabel); ArrayList<Object> fileSpecs = enDecryptInputOutputInternetFiles.get(inputFileLabel);
int urlType = (int) fileSpecs.get(0); int urlType = (int) fileSpecs.get(0);
String url = (String) fileSpecs.get(1); String url = (String) fileSpecs.get(1);
try { try {
if (urlType == FILEFILEURL || urlType == NONSPECIFICFILEURL) { if (urlType == FILEFILEURL) {
URLConnection openURL = new URL(url).openConnection(); URLConnection openURL = new URL(url).openConnection();
openURL.addRequestProperty("User-Agent", "Mozilla/5.0"); openURL.addRequestProperty("User-Agent", "Mozilla/5.0");
fileEncrypt.encryptFile(openURL.getInputStream(), new FileOutputStream((File) fileSpecs.get(2)), buffer); fileEncrypt.encryptFileLineByLine(openURL.getInputStream(), new FileOutputStream((File) fileSpecs.get(2)));
} else if (urlType == DATAFILEURL) { } else if (urlType == DATAFILEURL) {
final int dataStartIndex = url.indexOf(",") + 1; final int dataStartIndex = url.indexOf(",") + 1;
final String data = url.substring(dataStartIndex); final String data = url.substring(dataStartIndex);
byte[] decoded = java.util.Base64.getDecoder().decode(data); byte[] decoded = java.util.Base64.getDecoder().decode(data);
fileEncrypt.encryptFile(new ByteArrayInputStream(decoded), new FileOutputStream((File) fileSpecs.get(2)), buffer); fileEncrypt.encryptFileAllInOne(decoded, new FileOutputStream((File) fileSpecs.get(2)));
} else if (urlType == NONSPECIFICFILEURL) {
URLConnection openURL = new URL(url).openConnection();
openURL.addRequestProperty("User-Agent", "Mozilla/5.0");
fileEncrypt.encryptFileLineByLine(openURL.getInputStream(), new FileOutputStream((File) fileSpecs.get(2)));
} }
} catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | NoSuchPaddingException e) { } catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -868,25 +847,17 @@ public class Controller implements Initializable {
BufferedImage bufferedImage = enDecryptInputOutputClipboardImages.get(inputFileLabel); BufferedImage bufferedImage = enDecryptInputOutputClipboardImages.get(inputFileLabel);
try { try {
ImageIO.write(bufferedImage, "png", byteArrayOutputStream); ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
fileEncrypt.encryptFile(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), new FileOutputStream(outputFileList.get(0).getAbsoluteFile()), buffer); fileEncrypt.encryptFileAllInOne(byteArrayOutputStream.toByteArray(), new FileOutputStream(outputFileList.get(0).getAbsoluteFile()));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage())); Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage()));
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidKeySpecException e) { } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | BadPaddingException | InvalidKeySpecException | IllegalBlockSizeException e) {
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
try { try {
File inputFile = new File(inputFileLabel.getText()); fileEncrypt.encryptFileLineByLine(inputFileLabel.getText(), outputFileList.get(0).getAbsolutePath());
if (inputFile.isFile()) { } catch (NoSuchPaddingException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException e) {
fileEncrypt.encryptFile(new FileInputStream(inputFile), new FileOutputStream(outputFileList.get(0)), buffer);
} else {
fileEncrypt.encryptDirectory(inputFileLabel.getText(), outputFileList.get(0).getAbsolutePath(), ".cryptoGX", buffer);
if (!outputFileList.get(0).isDirectory()) {
Platform.runLater(() -> warningAlert("Couldn't create directory\n '" + outputFileList.get(0).getAbsolutePath() + "'.\nTry again or restart cryptoGX with admin privileges"));
}
}
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -920,8 +891,6 @@ public class Controller implements Initializable {
/** /**
* <p>Decrypt all files given files. * <p>Decrypt all files given files.
* Get called if file 'Decrypt' button is pressed</p> * Get called if file 'Decrypt' button is pressed</p>
*
* @since 1.0.0
*/ */
public void fileDecryptButton() { public void fileDecryptButton() {
final byte[] salt; final byte[] salt;
@ -948,8 +917,7 @@ public class Controller implements Initializable {
totalThreads.getAndIncrement(); totalThreads.getAndIncrement();
Label inputFileLabel = entry.getKey(); Label inputFileLabel = entry.getKey();
ArrayList<File> outputFileList = entry.getValue(); ArrayList<File> outputFileList = entry.getValue();
String fileEnDecryptAlgorithm = fileEnDecryptAlgorithmBox.getSelectionModel().getSelectedItem(); EnDecrypt.AES fileDecrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt);
EnDecrypt.AES fileDecrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt, Integer.parseInt(fileEnDecryptAlgorithm.substring(fileEnDecryptAlgorithm.indexOf('-') + 1)));
if (enDecryptInputOutputInternetFiles.containsKey(entry.getKey())) { if (enDecryptInputOutputInternetFiles.containsKey(entry.getKey())) {
ArrayList<Object> imageSpecs = enDecryptInputOutputInternetFiles.get(entry.getKey()); ArrayList<Object> imageSpecs = enDecryptInputOutputInternetFiles.get(entry.getKey());
int urlType = (int) imageSpecs.get(0); int urlType = (int) imageSpecs.get(0);
@ -958,19 +926,18 @@ public class Controller implements Initializable {
if (urlType == FILEFILEURL) { if (urlType == FILEFILEURL) {
URLConnection openURL = new URL(url).openConnection(); URLConnection openURL = new URL(url).openConnection();
openURL.addRequestProperty("User-Agent", "Mozilla/5.0"); openURL.addRequestProperty("User-Agent", "Mozilla/5.0");
fileDecrypt.decryptFile(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)), buffer); fileDecrypt.decryptFileLineByLine(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)));
fileDecrypt.decryptFile(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)), buffer);
} else if (urlType == DATAFILEURL) { } else if (urlType == DATAFILEURL) {
final int dataStartIndex = url.indexOf(",") + 1; final int dataStartIndex = url.indexOf(",") + 1;
final String data = url.substring(dataStartIndex); final String data = url.substring(dataStartIndex);
byte[] decoded = java.util.Base64.getDecoder().decode(data); byte[] decoded = java.util.Base64.getDecoder().decode(data);
fileDecrypt.decryptFile(new ByteArrayInputStream(decoded), new FileOutputStream((File) imageSpecs.get(2)), buffer); fileDecrypt.decryptFileAllInOne(decoded, new FileOutputStream((File) imageSpecs.get(2)));
} else if (urlType == NONSPECIFICFILEURL) { } else if (urlType == NONSPECIFICFILEURL) {
URLConnection openURL = new URL(url).openConnection(); URLConnection openURL = new URL(url).openConnection();
openURL.addRequestProperty("User-Agent", "Mozilla/5.0"); openURL.addRequestProperty("User-Agent", "Mozilla/5.0");
fileDecrypt.decryptFile(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)), buffer); fileDecrypt.decryptFileLineByLine(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)));
} }
} catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | NoSuchPaddingException e) { } catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -981,25 +948,17 @@ public class Controller implements Initializable {
BufferedImage bufferedImage = enDecryptInputOutputClipboardImages.get(inputFileLabel); BufferedImage bufferedImage = enDecryptInputOutputClipboardImages.get(inputFileLabel);
try { try {
ImageIO.write(bufferedImage, "png", byteArrayOutputStream); ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
fileDecrypt.decryptFile(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), new FileOutputStream(outputFileList.get(1).getAbsolutePath()), buffer); fileDecrypt.decryptFileAllInOne(byteArrayOutputStream.toByteArray(), new FileOutputStream(outputFileList.get(1).getAbsolutePath()));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage())); Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage()));
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidKeySpecException e) { } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | BadPaddingException | InvalidKeySpecException | IllegalBlockSizeException e) {
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
try { try {
File inputFile = new File(inputFileLabel.getText()); fileDecrypt.decryptFileLineByLine(inputFileLabel.getText(), outputFileList.get(1).getAbsolutePath());
if (inputFile.isFile()) { } catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
fileDecrypt.decryptFile(new FileInputStream(inputFile), new FileOutputStream(outputFileList.get(1)), buffer);
} else {
fileDecrypt.decryptDirectory(inputFileLabel.getText(), outputFileList.get(1).getAbsolutePath(), "@.cryptoGX@", buffer);
if (!outputFileList.get(1).isDirectory()) {
Platform.runLater(() -> warningAlert("Couldn't create directory\n '" + outputFileList.get(1).getAbsolutePath() + "'.\nTry again or restart cryptoGX with admin privileges"));
}
}
} catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -1036,8 +995,6 @@ public class Controller implements Initializable {
/** /**
* <p>Cancels the file en- / decryption. * <p>Cancels the file en- / decryption.
* Get called if the file en- / decrypt 'Cancel' button is pressed</p> * Get called if the file en- / decrypt 'Cancel' button is pressed</p>
*
* @since 1.12.0
*/ */
public void fileEnDecryptCancelButton() { public void fileEnDecryptCancelButton() {
for (Iterator<Thread> iterator = getFileEnDecryptThreads().iterator(); iterator.hasNext();) { for (Iterator<Thread> iterator = getFileEnDecryptThreads().iterator(); iterator.hasNext();) {
@ -1060,8 +1017,6 @@ public class Controller implements Initializable {
* <p>Synchronized method to get the list of threads which delete files</p> * <p>Synchronized method to get the list of threads which delete files</p>
* *
* @return list of threads which delete files * @return list of threads which delete files
*
* @since 1.2.0
*/ */
private synchronized List<Thread> getFileDeleteThreads() { private synchronized List<Thread> getFileDeleteThreads() {
return fileDeleteThreads; return fileDeleteThreads;
@ -1071,8 +1026,6 @@ public class Controller implements Initializable {
* <p>Synchronized method to get the number of threads which delete files</p> * <p>Synchronized method to get the number of threads which delete files</p>
* *
* @return number of threads which delete files * @return number of threads which delete files
*
* @since 1.2.0
*/ */
private synchronized int getFileDeleteThreadsSize() { private synchronized int getFileDeleteThreadsSize() {
return fileDeleteThreads.size(); return fileDeleteThreads.size();
@ -1082,8 +1035,6 @@ public class Controller implements Initializable {
* <p>Synchronized method to add a thread to the file delete list of current running file delete threads</p> * <p>Synchronized method to add a thread to the file delete list of current running file delete threads</p>
* *
* @param thread that should be added * @param thread that should be added
*
* @since 1.2.0
*/ */
private synchronized void addFileDeleteThread(Thread thread) { private synchronized void addFileDeleteThread(Thread thread) {
fileDeleteThreads.add(thread); fileDeleteThreads.add(thread);
@ -1093,8 +1044,6 @@ public class Controller implements Initializable {
* <p>Synchronized method to remove a thread from the file delete list of current file delete threads</p> * <p>Synchronized method to remove a thread from the file delete list of current file delete threads</p>
* *
* @param thread that should be removed * @param thread that should be removed
*
* @since 1.2.0
*/ */
private synchronized void removeFileDeleteThread(Thread thread) { private synchronized void removeFileDeleteThread(Thread thread) {
fileDeleteThreads.remove(thread); fileDeleteThreads.remove(thread);
@ -1104,8 +1053,6 @@ public class Controller implements Initializable {
* <p>Adds a file that should be deleted</p> * <p>Adds a file that should be deleted</p>
* *
* @param file that should be added * @param file that should be added
*
* @since 1.2.0
*/ */
private void fileDeleteAddFile(File file) { private void fileDeleteAddFile(File file) {
for (File f: deleteInputFiles.values()) { for (File f: deleteInputFiles.values()) {
@ -1117,8 +1064,12 @@ public class Controller implements Initializable {
newLabel.setOnKeyTyped(this::keyTypedTooltip); newLabel.setOnKeyTyped(this::keyTypedTooltip);
newLabel.setOnMouseMoved(this::mouseOverEntryTooltip); newLabel.setOnMouseMoved(this::mouseOverEntryTooltip);
newLabel.setOnMouseExited(event -> mouseExitEntryTooltip()); newLabel.setOnMouseExited(event -> mouseExitEntryTooltip());
newLabel.setOnMouseClicked(event -> fileDeleteSelected(newLabel)); newLabel.setOnMouseClicked(event -> {
newLabel.setContextMenu(fileDeleteInputContextMenu); fileDeleteSelected(newLabel);
if (event.getButton() == MouseButton.SECONDARY) {
fileDeleteInputContextMenu.show(newLabel, event.getScreenX(), event.getScreenY());
}
});
fileDeleteInputFiles.getChildren().add(newLabel); fileDeleteInputFiles.getChildren().add(newLabel);
deleteInputFiles.put(newLabel, file.getAbsoluteFile()); deleteInputFiles.put(newLabel, file.getAbsoluteFile());
} }
@ -1128,8 +1079,6 @@ public class Controller implements Initializable {
* Get called if the user click an non-highlighted item in the file delete box</p> * Get called if the user click an non-highlighted item in the file delete box</p>
* *
* @param changeLabel is the label that the user has clicked * @param changeLabel is the label that the user has clicked
*
* @since 1.2.0
*/ */
private void fileDeleteSelected(Label changeLabel) { private void fileDeleteSelected(Label changeLabel) {
if (changeLabel != null) { if (changeLabel != null) {
@ -1147,9 +1096,17 @@ public class Controller implements Initializable {
* <p>Deletes an entry for file delete. * <p>Deletes an entry for file delete.
* Get called if the user presses 'del' or delete the entry in the file delete box via the right click tooltip</p> * Get called if the user presses 'del' or delete the entry in the file delete box via the right click tooltip</p>
* *
* @param label that should be deleted * @see Controller#fileEnDecryptDeleteEntry(Label)
*/
private void fileDeleteDeleteEntry() {
fileEnDecryptDeleteEntry(choosedLabel);
}
/**
* <p>Deletes an entry for file delete.
* Get called if the user presses 'del' or delete the entry in the file delete box via the right click tooltip</p>
* *
* @since 1.12.0 * @param label that should be deleted
*/ */
private void fileDeleteDeleteEntry(Label label) { private void fileDeleteDeleteEntry(Label label) {
deleteInputFiles.remove(choosedLabel); deleteInputFiles.remove(choosedLabel);
@ -1180,66 +1137,47 @@ public class Controller implements Initializable {
/** /**
* <p>Opens a file chooser GUI where the user can select the files that should be en- / decrypted. * <p>Opens a file chooser GUI where the user can select the files that should be en- / decrypted.
* Get called if the 'Choose files...' in the delete section button is pressed</p> * Get called if the 'Choose files...' in the delete section button is pressed</p>
*
* @since 1.12.0
*/ */
public void fileDeleteChooseFiles() { public void fileDeleteChoose() {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Choose files"); fileChooser.setTitle("Choose files");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All Files", "*.*")); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All Files", "*.*"));
List<File> files = fileChooser.showOpenMultipleDialog(rootWindow.getScene().getWindow()); List<File> files = fileChooser.showOpenMultipleDialog(rootWindow.getScene().getWindow());
try { try {
if (files.size() > 0) { if (files.size() >= 1) {
files.forEach(this::fileDeleteAddFile); files.forEach(file -> fileDeleteAddFile(file));
} }
} catch (NullPointerException e) { } catch (NullPointerException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
/**
* <p>Opens a directory chooser GUI where the user can select the directories that should be en- / decrypted.
* Get called if the 'Choose directories...' in the delete section button is pressed</p>
*
* @since 1.12.0
*/
public void fileDeleteChooseDirectories() {
DirectoryChooser directoryChooser = new DirectoryChooser();
directoryChooser.setTitle("Choose directories");
File file = directoryChooser.showDialog(rootWindow.getScene().getWindow());
try {
fileDeleteAddFile(file);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
/** /**
* <p>Get called if user drags a file over the delete file box</p> * <p>Get called if user drags a file over the delete file box</p>
* *
* @param event source * @param event source
*
* @since 1.2.0
*/ */
public void onFileDeleteDragOver(DragEvent event) { public void onFileDeleteDragOver(DragEvent event) {
Dragboard dragboard = event.getDragboard(); Dragboard dragboard = event.getDragboard();
if (event.getGestureSource() != fileDeleteInputFiles && dragboard.hasFiles()) { if (event.getGestureSource() != fileDeleteInputFiles && dragboard.hasFiles()) {
if (dragboard.getFiles().size() == 1 && dragboard.getFiles().get(0).isDirectory()) {
return;
} else {
event.acceptTransferModes(TransferMode.COPY_OR_MOVE); event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
} }
} }
}
/** /**
* <p>Get called if the user drops the dragged file over the delete file box</p> * <p>Get called if the user drops the dragged file over the delete file box</p>
* *
* @param event source * @param event source
*
* @since 1.2.0
*/ */
public void onFileDeleteDragNDrop(DragEvent event) { public void onFileDeleteDragNDrop(DragEvent event) {
Dragboard dragboard = event.getDragboard(); Dragboard dragboard = event.getDragboard();
if (dragboard.hasFiles()) { if (dragboard.hasFiles()) {
dragboard.getFiles().forEach(file -> { dragboard.getFiles().forEach(file -> {
if (file.isFile() || file.isDirectory()) { if (file.isFile()) {
fileDeleteAddFile(file); fileDeleteAddFile(file);
} }
}); });
@ -1249,15 +1187,14 @@ public class Controller implements Initializable {
/** /**
* <p>Delete all given files. * <p>Delete all given files.
* Get called if 'Delete' button is pressed</p> * Get called if 'Delete' button is pressed</p>
*
* @since 1.2.0
*/ */
public void fileDelete() { public void fileDelete() {
if (!fileDeleteLoading && !deleteInputFiles.isEmpty()) { if (!fileDeleteLoading && !deleteInputFiles.isEmpty()) {
fileDeleteLoadingImage.setImage(loadingImage); fileDeleteLoadingImage.setImage(loadingImage);
} }
int deleteIterations = Integer.parseInt(fileDeleteIterationsEntry.getText()); Iterator<Map.Entry<Label, File>> deleteIterator = deleteInputFiles.entrySet().iterator();
for (Map.Entry<Label, File> map : deleteInputFiles.entrySet()) { while(deleteIterator.hasNext()) {
Map.Entry<Label, File> map = deleteIterator.next();
Label label = map.getKey(); Label label = map.getKey();
File file = map.getValue(); File file = map.getValue();
Thread thread = new Thread(() -> { Thread thread = new Thread(() -> {
@ -1272,13 +1209,10 @@ public class Controller implements Initializable {
} }
} }
totalThreads.getAndIncrement(); totalThreads.getAndIncrement();
String deleteFile = file.getAbsolutePath();
try { try {
if (file.isFile()) { SecureDelete.deleteFileLineByLine(deleteFile, Integer.parseInt(fileDeleteIterationsEntry.getText()));
SecureDelete.deleteFile(file, deleteIterations, buffer); } catch (NoSuchAlgorithmException | IOException e) {
} else if (file.isDirectory()) {
SecureDelete.deleteDirectory(file.getAbsolutePath(), deleteIterations, buffer);
}
} catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
if ((getFileDeleteThreadsSize() - 1) <= 0) { if ((getFileDeleteThreadsSize() - 1) <= 0) {
@ -1302,8 +1236,6 @@ public class Controller implements Initializable {
/** /**
* <p>Cancels the file en- / decryption. * <p>Cancels the file en- / decryption.
* Get called if the file delete 'Cancel' button is pressed</p> * Get called if the file delete 'Cancel' button is pressed</p>
*
* @since 1.12.0
*/ */
public void fileDeleteCancelButton() { public void fileDeleteCancelButton() {
for (Iterator<Thread> iterator = getFileDeleteThreads().iterator(); iterator.hasNext();) { for (Iterator<Thread> iterator = getFileDeleteThreads().iterator(); iterator.hasNext();) {
@ -1329,14 +1261,14 @@ public class Controller implements Initializable {
* @param resources * @param resources
* The resources used to localize the root object, or <tt>null</tt> if * The resources used to localize the root object, or <tt>null</tt> if
* the root object was not localized. * the root object was not localized.
*
* @since 1.0.0
*/ */
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
//-----general-----// //-----general-----//
currentConfigSettings.put("encryptHash", configDefaultEncryptHash);
currentConfigSettings.put("textKey", configDefaultTextKey); currentConfigSettings.put("textKey", configDefaultTextKey);
currentConfigSettings.put("textSalt", configDefaultTextSalt); currentConfigSettings.put("textSalt", configDefaultTextSalt);
currentConfigSettings.put("textAlgorithm", configDefaultTextAlgorithm); currentConfigSettings.put("textAlgorithm", configDefaultTextAlgorithm);
@ -1351,6 +1283,9 @@ public class Controller implements Initializable {
currentConfigSettings.put("removeFromFileBox", String.valueOf(configDefaultRemoveFileFromFileBox)); currentConfigSettings.put("removeFromFileBox", String.valueOf(configDefaultRemoveFileFromFileBox));
currentConfigSettings.put("limitNumberOfThreads", String.valueOf(configDefaultLimitNumberOfThreads)); currentConfigSettings.put("limitNumberOfThreads", String.valueOf(configDefaultLimitNumberOfThreads));
textAlgorithms.add("AES");
fileEnDecryptAlgorithms.add("AES");
menubar.setOnMouseDragged(event -> { menubar.setOnMouseDragged(event -> {
Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
stage.setX(event.getScreenX() + menubarX); stage.setX(event.getScreenX() + menubarX);
@ -1365,9 +1300,9 @@ public class Controller implements Initializable {
rootWindow.setOnKeyReleased(event -> { rootWindow.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.DELETE && choosedLabelType != null) { if (event.getCode() == KeyCode.DELETE && choosedLabelType != null) {
if (choosedLabelType.equals("ENDECRYPT")) { if (choosedLabelType.equals("ENDECRYPT")) {
fileEnDecryptDeleteEntry(choosedLabel); fileEnDecryptDeleteEntry();
} else if (choosedLabelType.equals("DELETE")) { } else if (choosedLabelType.equals("DELETE")) {
fileDeleteDeleteEntry(choosedLabel); fileDeleteDeleteEntry();
} }
} }
}); });
@ -1428,6 +1363,7 @@ public class Controller implements Initializable {
loadSettings.setOnAction(event -> { loadSettings.setOnAction(event -> {
try { try {
currentConfigSettings = (HashMap<String, String>) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0]; currentConfigSettings = (HashMap<String, String>) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0];
System.out.println(currentConfigSettings);
textKeyEntry.setText(currentConfigSettings.get("textKey")); textKeyEntry.setText(currentConfigSettings.get("textKey"));
textSaltEntry.setText(currentConfigSettings.get("textSalt")); textSaltEntry.setText(currentConfigSettings.get("textSalt"));
textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm")); textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm"));
@ -1444,9 +1380,9 @@ public class Controller implements Initializable {
e.printStackTrace(); e.printStackTrace();
} catch (ArrayIndexOutOfBoundsException ex) { } catch (ArrayIndexOutOfBoundsException ex) {
try { try {
SecureDelete.deleteFile(config, 5, buffer); SecureDelete.deleteFileLineByLine(config, 5);
isConfig = false; isConfig = false;
} catch (IOException e) { } catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -1466,9 +1402,9 @@ public class Controller implements Initializable {
File file = fileChooser.showOpenDialog(rootWindow.getScene().getWindow()); File file = fileChooser.showOpenDialog(rootWindow.getScene().getWindow());
if (file != null) { if (file != null) {
if (isConfig) { if (isConfig) {
writeSettings(config, readSettings(file)); readUserSettings(file).forEach((Config::addSetting));
} else { } else {
writeSettings(config, readSettings(file)); writeConfig(readUserSettings(file));
isConfig = true; isConfig = true;
} }
} }
@ -1476,31 +1412,24 @@ public class Controller implements Initializable {
//-----text------// //-----text------//
textAlgorithmBox.setItems(FXCollections.observableArrayList(Utils.algorithms.keySet())); textAlgorithmBox.setItems(FXCollections.observableArrayList(textAlgorithms));
textAlgorithmBox.setValue(Utils.algorithms.keySet().toArray(new String[Utils.algorithms.size()])[0]); textAlgorithmBox.setValue(textAlgorithms.get(0));
//-----fileEnDecrypt-----// //-----fileEnDecrypt-----//
fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(Utils.algorithms.keySet())); fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(fileEnDecryptAlgorithms));
fileEnDecryptAlgorithmBox.setValue(Utils.algorithms.keySet().toArray(new String[Utils.algorithms.size()])[0]); fileEnDecryptAlgorithmBox.setValue(fileEnDecryptAlgorithms.get(0));
MenuItem enDecryptRemove = new MenuItem(); MenuItem enDecryptRemove = new MenuItem();
enDecryptRemove.setText("Remove"); enDecryptRemove.setText("Remove");
enDecryptRemove.setOnAction(removeEvent -> fileEnDecryptDeleteEntry(choosedLabel)); enDecryptRemove.setOnAction(removeEvent -> fileEnDecryptDeleteEntry());
MenuItem enDecryptChangeDest = new MenuItem(); MenuItem enDecryptChangeDest = new MenuItem();
enDecryptChangeDest.setText("Change output file / directory"); enDecryptChangeDest.setText("Change output file");
enDecryptChangeDest.setOnAction(outputFileChangeEvent -> { enDecryptChangeDest.setOnAction(outputFileChangeEvent -> {
File file; FileChooser fileDestChooser = new FileChooser();
if (new File(choosedLabel.getText()).isFile()) { fileDestChooser.setTitle("Choose or create new file");
FileChooser destChooser = new FileChooser(); fileDestChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*"));
destChooser.setTitle("Choose or create new file"); File file = fileDestChooser.showSaveDialog(rootWindow.getScene().getWindow());
destChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*"));
file = destChooser.showSaveDialog(rootWindow.getScene().getWindow());
} else {
DirectoryChooser destChooser = new DirectoryChooser();
destChooser.setTitle("Choose or create new directory");
file = destChooser.showDialog(rootWindow.getScene().getWindow());
}
if (file != null) { if (file != null) {
for (Map.Entry<Label, ArrayList<File>> entry : enDecryptInputOutputFiles.entrySet()) { for (Map.Entry<Label, ArrayList<File>> entry : enDecryptInputOutputFiles.entrySet()) {
if (entry.getKey().getText().equals(choosedLabel.getText())) { if (entry.getKey().getText().equals(choosedLabel.getText())) {
@ -1567,15 +1496,19 @@ public class Controller implements Initializable {
fileOutputFileChangeDest.setDisable(true); fileOutputFileChangeDest.setDisable(true);
getChoosedLabelOutputFileFolder.setDisable(true); getChoosedLabelOutputFileFolder.setDisable(true);
fileEncryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> fileOutputFilesChangeText(choosedLabel, newValue, fileDecryptOutputFile.getText())); fileEncryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> {
fileDecryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> fileOutputFilesChangeText(choosedLabel, fileEncryptOutputFile.getText(), newValue)); fileOutputFilesChangeText(choosedLabel, newValue, fileDecryptOutputFile.getText());
});
fileDecryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> {
fileOutputFilesChangeText(choosedLabel, fileEncryptOutputFile.getText(), newValue);
});
//-----fileDelete-----// //-----fileDelete-----//
MenuItem deleteRemove = new MenuItem(); MenuItem deleteRemove = new MenuItem();
deleteRemove.setText("Remove"); deleteRemove.setText("Remove");
deleteRemove.setOnAction(removeEvent -> fileDeleteDeleteEntry(choosedLabel)); deleteRemove.setOnAction(removeEvent -> fileDeleteDeleteEntry());
fileDeleteInputContextMenu.getItems().add(deleteRemove); fileDeleteInputContextMenu.getItems().addAll(deleteRemove);
ContextMenu fileDeleteInputFilesMenu = new ContextMenu(); ContextMenu fileDeleteInputFilesMenu = new ContextMenu();
MenuItem deletePaste = new MenuItem(); MenuItem deletePaste = new MenuItem();
@ -1617,6 +1550,7 @@ public class Controller implements Initializable {
Platform.runLater(() -> { Platform.runLater(() -> {
try { try {
currentConfigSettings = (HashMap<String, String>) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0]; currentConfigSettings = (HashMap<String, String>) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0];
System.out.println(currentConfigSettings);
textKeyEntry.setText(currentConfigSettings.get("textKey")); textKeyEntry.setText(currentConfigSettings.get("textKey"));
textSaltEntry.setText(currentConfigSettings.get("textSalt")); textSaltEntry.setText(currentConfigSettings.get("textSalt"));
textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm")); textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm"));
@ -1633,9 +1567,9 @@ public class Controller implements Initializable {
e.printStackTrace(); e.printStackTrace();
} catch (ArrayIndexOutOfBoundsException ex) { } catch (ArrayIndexOutOfBoundsException ex) {
try { try {
SecureDelete.deleteFile(config, 5, buffer); SecureDelete.deleteFileLineByLine(config, 5);
isConfig = false; isConfig = false;
} catch (IOException e) { } catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -0,0 +1,531 @@
package org.blueshard.cryptogx;
import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;
public class EnDecrypt {
public static class AES extends Thread {
private int iterations = 1000;
private int keyLength = 256;
private final String key;
private final byte[] salt;
public AES(String key, byte[] salt) {
this.key = key;
this.salt = salt;
}
public AES(String key, byte[] salt, int iterations) {
this.key = key;
this.salt = salt;
this.iterations = iterations;
}
public AES(String key, byte[] salt, int iterations, int keyLength) {
this.key = key;
this.salt = salt;
this.iterations = iterations;
this.keyLength = keyLength;
}
/**
* <p>Creates a secret key from given (plain text) key and salt</p>
*
* @param key from which a secret key should be created
* @param salt from which a secret key should be created
* @return the secret key
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public byte[] createSecretKey(String key, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
KeySpec keySpec = new PBEKeySpec(key.toCharArray(), salt, this.iterations, keyLength);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
return factory.generateSecret(keySpec).getEncoded();
}
/**
* <p>Writes {@param inputStream} to {@param outputStream}</p>
*
* @param inputStream from which is written
* @param outputStream to which is written
* @param buffer
* @throws IOException
*/
public static void writeLineByLine(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws IOException {
int numOfBytesRead;
while ((numOfBytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, numOfBytesRead);
}
outputStream.close();
inputStream.close();
}
/**
* <p>Encrypts a file randomly line by line</p>
*
* @see EnDecrypt.AES#encryptRandomLineByLine(InputStream, OutputStream, byte[])
*/
public static void encryptFileRandomLineByLine(File inputFile, File outputFile, byte[] buffer) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException {
encryptRandomLineByLine(new FileInputStream(inputFile), new FileOutputStream(outputFile), buffer);
}
/**
* <p>Encrypts a {@link InputStream} randomly line by line</p>
*
* @param inputStream that should be encrypted
* @param outputStream to which the encrypted {@param inputStream} should be written to
* @param buffer
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
* @throws InvalidAlgorithmParameterException
*/
public static void encryptRandomLineByLine(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException {
KeyGenerator randomKey = KeyGenerator.getInstance("AES");
Key secretKey = new SecretKeySpec(randomKey.generateKey().getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
writeLineByLine(cipherInputStream, outputStream, buffer);
}
/**
* <p>En- / decrypts the {@param inputFile}</p>
*
* @param cipherMode says if the file should be en- or decrypted
* @param inputFile that should be en- / decrypted
* @param outputFile to which the en- / decrypted {@param inputFile} should be written to
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public void enDecryptFileAllInOne(int cipherMode, File inputFile, File outputFile) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, BadPaddingException, IllegalBlockSizeException {
Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(cipherMode, secretKey);
FileInputStream inputStream = new FileInputStream(inputFile);
byte[] inputBytes = new byte[(int) inputFile.length()];
inputStream.read(inputBytes);
byte[] outputBytes = cipher.doFinal(inputBytes);
FileOutputStream outputStream = new FileOutputStream(outputFile);
outputStream.write(outputBytes);
inputStream.close();
outputStream.close();
}
/**
* <p>En- / decrypts the {@param inputBytes}</p>
*
* @param cipherMode says if the file should be en- or decrypted
* @param inputBytes that should be en- / decrypted
* @param outputStream to which the en- / decrypted {@param inputFile} should be written to
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public void enDecryptFileAllInOne(int cipherMode, byte[] inputBytes, OutputStream outputStream) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, BadPaddingException, IllegalBlockSizeException {
Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(cipherMode, secretKey);
byte[] outputBytes = cipher.doFinal(inputBytes);
outputStream.write(outputBytes);
outputStream.close();
}
/**
* <p>En- / decrypts the {@param inputFile}</p>
*
* @param cipherMode says if the file should be en- or decrypted
* @param inputFile that should be en- / decrypted
* @param outputFile to which the en- / decrypted {@param inputFile} should be written to
* @param buffer
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
* @throws InvalidAlgorithmParameterException
*/
public void enDecryptLineByLine(int cipherMode, File inputFile, File outputFile, byte[] buffer) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException {
Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(cipherMode, secretKey);
FileInputStream fileInputStream = new FileInputStream(inputFile);
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
if (cipherMode == Cipher.ENCRYPT_MODE) {
CipherInputStream cipherInputStream = new CipherInputStream(fileInputStream, cipher);
writeLineByLine(cipherInputStream, fileOutputStream, buffer);
} else if (cipherMode == Cipher.DECRYPT_MODE) {
CipherOutputStream cipherOutputStream = new CipherOutputStream(fileOutputStream, cipher);
writeLineByLine(fileInputStream, cipherOutputStream, buffer);
}
}
/**
* <p>En- / decrypts the {@param inputStream}</p>
*
* @param cipherMode says if the file should be en- or decrypted
* @param inputStream that should be en- / decrypted
* @param outputStream to which the en- / decrypted {@param inputFile} should be written to
* @param buffer
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
* @throws InvalidAlgorithmParameterException
*/
public void enDecryptLineByLine(int cipherMode, InputStream inputStream, OutputStream outputStream, byte[] buffer) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException {
Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(cipherMode, secretKey);
if (cipherMode == Cipher.ENCRYPT_MODE) {
CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
writeLineByLine(cipherInputStream, outputStream, buffer);
} else if (cipherMode == Cipher.DECRYPT_MODE) {
CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher);
writeLineByLine(inputStream, cipherOutputStream, buffer);
}
}
/**
* <p>Encrypt {@param bytes} randomly</p>
*
* @see EnDecrypt.AES#encryptRandom(byte[])
*/
public static String encryptRandom(String string) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
return encryptRandom(string.getBytes(StandardCharsets.UTF_8));
}
/**
* <p>Encrypt {@param bytes} randomly</p>
*
* @param bytes that should be encrypted
* @return the encrypted {@param bytes} as {@link String}
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static String encryptRandom(byte[] bytes) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
KeyGenerator randomKey = KeyGenerator.getInstance("AES");
Key secretKey = new SecretKeySpec(randomKey.generateKey().getEncoded(), "AES");
Cipher encryptRandomCipher = Cipher.getInstance("AES");
encryptRandomCipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(encryptRandomCipher.doFinal(bytes));
}
/**
* <p>Encrypts a file randomly at once</p>
*
* @see EnDecrypt.AES#encryptFileRandomAllInOne(File, File)
*/
public static void encryptFileRandomAllInOne(String inputFilename, String outputFilename) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
encryptFileRandomAllInOne(new File(inputFilename), new File(outputFilename));
}
/**
* <p>Encrypts a file randomly at once</p>
*
* @param inputFile that should be encrypted
* @param outputFile to which the encrypted file should be written to
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static void encryptFileRandomAllInOne(File inputFile, File outputFile) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, BadPaddingException, IllegalBlockSizeException {
KeyGenerator randomKey = KeyGenerator.getInstance("AES");
Key secretKey = new SecretKeySpec(randomKey.generateKey().getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
FileInputStream inputStream = new FileInputStream(inputFile);
byte[] inputBytes = new byte[(int) inputFile.length()];
inputStream.read(inputBytes);
byte[] outputBytes = cipher.doFinal(inputBytes);
FileOutputStream outputStream = new FileOutputStream(outputFile);
outputStream.write(outputBytes);
inputStream.close();
outputStream.close();
}
/**
* <p>Encrypts {@param inputFilename} randomly line by line and write it to {@param outputFilename}</p>
*
* @see EnDecrypt.AES#encryptRandomLineByLine(InputStream, OutputStream, byte[])
*/
public static void encryptFileRandomLineByLine(String inputFilename, String outputFilename) throws InvalidKeyException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchPaddingException, IOException {
encryptRandomLineByLine(new FileInputStream(inputFilename), new FileOutputStream(outputFilename), new byte[64]);
}
/**
* <p>Encrypts {@param inputFilename} randomly line by line and write it to {@param outputFilename}</p>
*
* @see EnDecrypt.AES#encryptRandomLineByLine(InputStream, OutputStream, byte[])
*/
public static void encryptFileRandomLineByLine(String inputFilename, String outputFilename, byte[] buffer) throws InvalidKeyException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchPaddingException, IOException {
encryptRandomLineByLine(new FileInputStream(inputFilename), new FileOutputStream(outputFilename), buffer);
}
/**
* <p>Decrypt encrypted {@param encryptedString}</p>
*
* @see EnDecrypt.AES#decrypt(byte[])
*/
public String decrypt(String encryptedString) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
Cipher decryptCipher = Cipher.getInstance("AES");
decryptCipher.init(Cipher.DECRYPT_MODE, secretKey);
return new String(decryptCipher.doFinal(Base64.getDecoder().decode(encryptedString)), StandardCharsets.UTF_8);
}
/**
* <p>Decrypt encrypted {@param bytes}</p>
*
* @param bytes that should be decrypted
* @return decrypted bytes
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
*/
public byte[] decrypt(byte[] bytes) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
return decrypt(Arrays.toString(bytes)).getBytes(StandardCharsets.UTF_8);
}
/**
* <p>Encrypt {@param bytes}</p>
*
* @see EnDecrypt.AES#encrypt(byte[])
*/
public String encrypt(String string) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
return Base64.getEncoder().encodeToString(encrypt(string.getBytes(StandardCharsets.UTF_8)));
}
/**
* <p>Encrypt {@param bytes}</p>
*
* @param bytes that should be encrypted
* @return encrypted bytes
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
*/
public byte[] encrypt(byte[] bytes) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
Cipher encryptCipher = Cipher.getInstance("AES");
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
return encryptCipher.doFinal(bytes);
}
/**
* <p>Decrypt encrypted {@param inputFilename} to {@param outputFilename} at once</p>
*
* @param inputFilename that should be decrypted
* @param outputFilename to which the decrypted content should be written to
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
*/
public void decryptFileAllInOne(String inputFilename, String outputFilename) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException {
enDecryptFileAllInOne(Cipher.DECRYPT_MODE, new File(inputFilename), new File(outputFilename));
}
/**
* <p>Decrypt encrypted {@param inputBytes} to {@param outputStream} at once</p>
*
* @param inputBytes that should be decrypted
* @param outputStream to which the decrypted content should be written to
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
*/
public void decryptFileAllInOne(byte[] inputBytes, OutputStream outputStream) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException {
enDecryptFileAllInOne(Cipher.DECRYPT_MODE, inputBytes, outputStream);
}
/**
* <p>Decrypt encrypted {@param inputFilename} to {@param outputFilename} line by line</p>
*
* @see EnDecrypt.AES#decryptFileLineByLine(InputStream, OutputStream, byte[])
*/
public void decryptFileLineByLine(String inputFilename, String outputFilename) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
enDecryptLineByLine(Cipher.DECRYPT_MODE, new File(inputFilename), new File(outputFilename), new byte[64]);
}
/**
* <p>Decrypt encrypted {@param inputStream} to {@param outputStream} line by line</p>
*
* @see EnDecrypt.AES#decryptFileLineByLine(InputStream, OutputStream, byte[])
*/
public void decryptFileLineByLine(InputStream inputStream, OutputStream outputStream) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
enDecryptLineByLine(Cipher.DECRYPT_MODE, inputStream, outputStream, new byte[64]);
}
/**
* <p>Decrypt encrypted {@param inputFilename} to {@param outputFilename} line by line</p>
*
* @see EnDecrypt.AES#decryptFileLineByLine(InputStream, OutputStream, byte[])
*/
public void decryptFileLineByLine(String inputFilename, String outputFilename, byte[] buffer) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
enDecryptLineByLine(Cipher.DECRYPT_MODE, new File(inputFilename), new File(outputFilename), buffer);
}
/**
* <p>Decrypt encrypted {@param inputStream} to {@param outputStream} line by line</p>
*
* @param inputStream that should be decrypted
* @param outputStream to which the decrypted content should be written to
* @param buffer
* @throws NoSuchPaddingException
* @throws InvalidAlgorithmParameterException
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
*/
public void decryptFileLineByLine(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
enDecryptLineByLine(Cipher.DECRYPT_MODE, inputStream, outputStream, buffer);
}
/**
* <p>DEncrypt {@param inputFilename} to {@param outputFilename} at once</p>
*
* @param inputFilename that should be encrypt
* @param outputFilename to which the encrypted content should be written to
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
*/
public void encryptFileAllInOne(String inputFilename, String outputFilename) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException {
enDecryptFileAllInOne(Cipher.ENCRYPT_MODE, new File(inputFilename), new File(outputFilename));
}
/**
* <p>Encrypt {@param inputBytes} to {@param outputStream} at once</p>
*
* @param inputBytes that should be encrypted
* @param outputStream to which the encrypted content should be written to
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
*/
public void encryptFileAllInOne(byte[] inputBytes, OutputStream outputStream) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException {
enDecryptFileAllInOne(Cipher.ENCRYPT_MODE, inputBytes, outputStream);
}
/**
* <p>Encrypt {@param inputFilename} to {@param outputFilename} line by line</p>
*
* @see EnDecrypt.AES#encryptFileLineByLine(InputStream, OutputStream, byte[])
*/
public void encryptFileLineByLine(String inputFilename, String outputFilename) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
enDecryptLineByLine(Cipher.ENCRYPT_MODE, new File(inputFilename), new File(outputFilename), new byte[64]);
}
/**
* <p>Encrypt {@param inputStream} to {@param outputStream} line by line</p>
*
* @see EnDecrypt.AES#encryptFileLineByLine(InputStream, OutputStream, byte[])
*/
public void encryptFileLineByLine(InputStream inputStream, OutputStream outputStream) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
enDecryptLineByLine(Cipher.ENCRYPT_MODE, inputStream, outputStream, new byte[64]);
}
/**
* <p>Encrypt {@param inputFilename} to {@param outputFilename} line by line</p>
*
* @see EnDecrypt.AES#encryptFileLineByLine(InputStream, OutputStream, byte[])
*/
public void encryptFileLineByLine(String inputFilename, String outputFilename, byte[] buffer) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
enDecryptLineByLine(Cipher.ENCRYPT_MODE, new File(inputFilename), new File(outputFilename), buffer);
}
/**
* <p>Encrypt {@param inputStream} to {@param outputStream} line by line</p>
*
* @param inputStream that should be encrypted
* @param outputStream to which the encrypted {@param inputStream} should be written to
* @param buffer
* @throws NoSuchPaddingException
* @throws InvalidAlgorithmParameterException
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
*/
public void encryptFileLineByLine(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
enDecryptLineByLine(Cipher.ENCRYPT_MODE, inputStream, outputStream, buffer);
}
}
}

View File

@ -1,13 +1,10 @@
/* /**
* @author bytedream
* @version 1.12.0
* *
* Some <code>@since</code> versions may be not correct, because the <code>@since</code> tag got added in * @author blueShard
* version 1.12.0 and I don't have all versions (1.0.0 - 1.11.0), so I cannot see when some methods were added * @version 1.11.0
*/ */
package org.bytedream.cryptogx; package org.blueshard.cryptogx;
import javafx.application.Application; import javafx.application.Application;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
@ -32,30 +29,28 @@ import java.security.spec.InvalidKeySpecException;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
/**
* <p>Main class<p/>
*
* @since 1.0.0
*/
public class Main extends Application { public class Main extends Application {
protected static final int NON_PORTABLE = 1; protected static final int NON_PORTABLE = 414729643;
protected static final int PORTABLE = 0; protected static final int PORTABLE = 245714766;
protected static final int TYPE = NON_PORTABLE; protected static final int TYPE = PORTABLE;
protected final static String configDefaultName = "";
protected final static String configDefaultEncryptHash = "";
protected final static String configDefaultTextKey = ""; protected final static String configDefaultTextKey = "";
protected final static String configDefaultTextSalt = ""; protected final static String configDefaultTextSalt = "";
protected final static String configDefaultTextAlgorithm = "AES-128"; protected final static String configDefaultTextAlgorithm = "AES";
protected final static String configDefaultFileEnDecryptKey = ""; protected final static String configDefaultFileEnDecryptKey = "";
protected final static String configDefaultFileEnDecryptSalt = ""; protected final static String configDefaultFileEnDecryptSalt = "";
protected final static String configDefaultFileEnDecryptAlgorithm = "AES-128"; protected final static String configDefaultFileEnDecryptAlgorithm = "AES";
protected final static int configDefaultFileDeleteIterations = 5; protected final static int configDefaultFileDeleteIterations = 5;
protected final static String configDefaultFileOutputPath = ""; protected final static String configDefaultFileOutputPath = "";
protected final static boolean configDefaultRemoveFileFromFileBox = false; protected final static boolean configDefaultRemoveFileFromFileBox = false;
protected final static boolean configDefaultLimitNumberOfThreads = true; protected final static boolean configDefaultLimitNumberOfThreads = true;
private final static byte[] buffer = new byte[64]; protected static ArrayList<String> textAlgorithms = new ArrayList<>();
protected static ArrayList<String> fileEnDecryptAlgorithms = new ArrayList<>();
private static Stage mainStage; private static Stage mainStage;
private double rootWindowX, rootWindowY; private double rootWindowX, rootWindowY;
@ -67,8 +62,6 @@ public class Main extends Application {
* *
* @param primaryStage of the GUI * @param primaryStage of the GUI
* @throws IOException if issues with loading 'mainGUI.fxml' * @throws IOException if issues with loading 'mainGUI.fxml'
*
* @since 1.0.0
*/ */
@Override @Override
public void start(Stage primaryStage) throws IOException { public void start(Stage primaryStage) throws IOException {
@ -81,8 +74,7 @@ public class Main extends Application {
primaryStage.setResizable(false); primaryStage.setResizable(false);
primaryStage.setTitle("cryptoGX"); primaryStage.setTitle("cryptoGX");
primaryStage.getIcons().add(new Image(getClass().getResource("resources/cryptoGX.png").toExternalForm())); primaryStage.getIcons().add(new Image(getClass().getResource("resources/cryptoGX.png").toExternalForm()));
Scene scene = new Scene(root); Scene scene = new Scene(root, 900, 470);
//Scene scene = new Scene(root, 900, 470);
scene.setOnMouseDragged(event -> { scene.setOnMouseDragged(event -> {
primaryStage.setX(event.getScreenX() + rootWindowX); primaryStage.setX(event.getScreenX() + rootWindowX);
@ -102,7 +94,7 @@ public class Main extends Application {
* Can also be used to en- / decrypt text and files or secure delete files without starting GUI</p> * Can also be used to en- / decrypt text and files or secure delete files without starting GUI</p>
* *
* @param args from the command line * @param args from the command line
* @return * @return status
* @throws BadPaddingException * @throws BadPaddingException
* @throws NoSuchAlgorithmException if wrong algorithm is given (command line) * @throws NoSuchAlgorithmException if wrong algorithm is given (command line)
* @throws IllegalBlockSizeException if wrong size for key is given (command line) * @throws IllegalBlockSizeException if wrong size for key is given (command line)
@ -111,24 +103,11 @@ public class Main extends Application {
* @throws InvalidKeySpecException * @throws InvalidKeySpecException
* @throws IOException if files cannot be en- / decrypted or deleted correctly (command line) * @throws IOException if files cannot be en- / decrypted or deleted correctly (command line)
* @throws InvalidAlgorithmParameterException if wrong algorithm parameters are given (command line) * @throws InvalidAlgorithmParameterException if wrong algorithm parameters are given (command line)
*
* @since 1.0.0
*/ */
public static void main(String[] args) throws BadPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IOException, InvalidAlgorithmParameterException { public static void main(String[] args) throws BadPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IOException, InvalidAlgorithmParameterException {
if (Main.TYPE == Main.PORTABLE) { if (Main.TYPE == Main.NON_PORTABLE) {
String system = System.getProperty("os.name").toLowerCase(); if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
if (system.startsWith("windows")) {
config = new File("C:\\Users\\" + System.getProperty("user.name") + "\\AppData\\Roaming\\cryptoGX\\cryptoGX.config"); config = new File("C:\\Users\\" + System.getProperty("user.name") + "\\AppData\\Roaming\\cryptoGX\\cryptoGX.config");
File directory = new File("C:\\Users\\" + System.getProperty("user.name") + "\\AppData\\Roaming\\cryptoGX");
if (!directory.isDirectory()) {
directory.mkdir();
}
} else if (system.startsWith("linux")) {
config = new File(System.getProperty("user.home") + "/.cryptoGX/cryptoGX.config");
File directory = new File(System.getProperty("user.home") + "/.cryptoGX/");
if (!directory.isDirectory()) {
directory.mkdir();
}
} else { } else {
config = new File("cryptoGX.config"); config = new File("cryptoGX.config");
} }
@ -137,6 +116,19 @@ public class Main extends Application {
} }
isConfig = config.isFile(); isConfig = config.isFile();
if (args.length == 0) { if (args.length == 0) {
String version = Runtime.class.getPackage().getImplementationVersion();
if (version.startsWith("1.")) {
if (Integer.parseInt(version.substring(2, 3)) < 8) {
System.out.println("1");
JOptionPane.showMessageDialog(null, "Please use java 1.8.0_240 to java 10.*", "ERROR", JOptionPane.ERROR_MESSAGE);
} else if (Integer.parseInt(version.substring(6, 9)) < 240) {
JOptionPane.showMessageDialog(null, "Please use java 1.8.0_240 to java 10.*", "ERROR", JOptionPane.ERROR_MESSAGE);
}
} else if (Integer.parseInt(version.substring(0, 2)) > 10) {
JOptionPane.showMessageDialog(null, "Please use java 1.8.0_240 to java 10.*", "ERROR", JOptionPane.ERROR_MESSAGE);
} else {
JOptionPane.showMessageDialog(null, "Please use java 1.8.0_240 to java 10.*", "ERROR", JOptionPane.ERROR_MESSAGE);
}
launch(args); launch(args);
} else { } else {
args[0] = args[0].replace("-", ""); args[0] = args[0].replace("-", "");
@ -148,7 +140,7 @@ public class Main extends Application {
" File en- / decryption\n" + " File en- / decryption\n" +
" encrypt: <cryptoGX jar file> AES <key> <salt> encrypt <path of file to encrypt> <encrypted file dest>\n" + " encrypt: <cryptoGX jar file> AES <key> <salt> encrypt <path of file to encrypt> <encrypted file dest>\n" +
" decrypt: <cryptoGX jar file> AES <key> <salt> decrypt <encrypted file path> <decrypted file dest>\n\n" + " decrypt: <cryptoGX jar file> AES <key> <salt> decrypt <encrypted file path> <decrypted file dest>\n\n" +
"File secure delete: <cryptoGX jar file> delete <iterations> <path of file to delete>"); //for <iterations> the argument 'default' can be used, which is 5 "File secure delete: <iterations> <path of file to delete>");
} else if (args[0].toLowerCase().equals("delete")) { } else if (args[0].toLowerCase().equals("delete")) {
if (args.length > 3) { if (args.length > 3) {
System.err.println("To many arguments were given, expected 3"); System.err.println("To many arguments were given, expected 3");
@ -156,28 +148,14 @@ public class Main extends Application {
System.err.println("To few arguments were given, expected 3"); System.err.println("To few arguments were given, expected 3");
} }
try { try {
if (args[1].equals("default")) { SecureDelete.deleteFileLineByLine(args[2], Integer.parseInt(args[1]));
args[1] = "5";
}
File deleteFile = new File(args[2]);
if (deleteFile.isFile()) {
SecureDelete.deleteFile(deleteFile, Integer.parseInt(args[1]), buffer);
} else if (deleteFile.isDirectory()) {
SecureDelete.deleteDirectory(args[2], Integer.parseInt(args[1]), buffer);
} else {
System.err.println("Couldn't find file " + args[4]);
System.exit(1);
}
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
System.err.println(args[1] + " must be a number\n Error: " + e.getMessage()); System.err.println(args[1] + " must be a number\n Error: " + e.getMessage());
} }
} else if (args[0].toLowerCase().equals("aes")) { } else if (args[0].toLowerCase().equals("aes")) {
if (args.length < 5) { if (args.length < 4) {
System.err.println("To few arguments were given"); System.err.println("To few arguments were given");
System.exit(1); System.exit(1);
} else if (args.length > 6) {
System.err.println("To many arguments were given");
System.exit(1);
} }
EnDecrypt.AES aes; EnDecrypt.AES aes;
if (args[2].isEmpty()) { if (args[2].isEmpty()) {
@ -186,53 +164,25 @@ public class Main extends Application {
aes = new EnDecrypt.AES(args[1], args[2].getBytes(StandardCharsets.UTF_8)); aes = new EnDecrypt.AES(args[1], args[2].getBytes(StandardCharsets.UTF_8));
} }
String type = args[3].toLowerCase(); String type = args[3].toLowerCase();
if (args.length == 5) {
if (type.equals("encrypt")) { if (type.equals("encrypt")) {
System.out.println(Base64.getEncoder().encodeToString(aes.encrypt(args[4].getBytes(StandardCharsets.UTF_8)))); System.out.println(aes.encrypt(args[4]));
} else if (type.equals("decrypt")) { } else if (type.equals("decrypt")) {
System.out.println(aes.decrypt(args[4])); System.out.println(aes.decrypt(args[4]));
} else { } else if (type.equals("fileencrypt") || type.equals("encryptfile")) {
System.err.println("Couldn't resolve argument " + args[3] + ", expected 'encrypt' or 'decrypt'"); aes.encryptFileLineByLine(args[4], args[5]);
System.exit(1); } else if (type.equals("filedecrypt") ||type.equals("decryptfile")) {
aes.decryptFileLineByLine(args[4], args[5]);
} }
} else {
if (type.equals("encrypt")) {
File inputFile = new File(args[4]);
if (inputFile.isFile()) {
aes.encryptFile(new FileInputStream(inputFile), new FileOutputStream(args[5]), new byte[64]);
} else if (inputFile.isDirectory()) {
aes.encryptDirectory(args[4], args[5], ".cryptoGX", new byte[64]);
} else {
System.err.println("Couldn't find file " + args[4]);
System.exit(1);
}
} else if (type.equals("decrypt")) {
File inputFile = new File(args[4]);
if (inputFile.isFile()) {
aes.decryptFile(new FileInputStream(inputFile), new FileOutputStream(args[5]), new byte[64]);
} else if (inputFile.isDirectory()) {
aes.decryptDirectory(args[4], args[5], "@.cryptoGX@", new byte[64]);
} else {
System.err.println("Couldn't find file " + args[4]);
System.exit(1);
}
} else {
System.err.println("Couldn't resolve argument " + args[3] + ", expected 'encrypt' or 'decrypt'");
System.exit(1);
} }
} }
System.exit(0); System.exit(0);
} }
}
}
/** /**
* <p>"Catch" all uncatched exceptions and opens an alert window</p> * <p>"Catch" all uncatched exceptions and opens an alert window</p>
* *
* @param thread which called this method * @param thread which called this method
* @param throwable of the thread which called the method * @param throwable of the thread which called the method
*
* @since 1.3.0
*/ */
private static void exceptionAlert(Thread thread, Throwable throwable) { private static void exceptionAlert(Thread thread, Throwable throwable) {
throwable.printStackTrace(); throwable.printStackTrace();
@ -243,9 +193,7 @@ public class Main extends Application {
Alert enDecryptError = new Alert(Alert.AlertType.ERROR, "Error: " + throwable, ButtonType.OK); Alert enDecryptError = new Alert(Alert.AlertType.ERROR, "Error: " + throwable, ButtonType.OK);
enDecryptError.initStyle(StageStyle.UNDECORATED); enDecryptError.initStyle(StageStyle.UNDECORATED);
enDecryptError.setTitle("Error"); enDecryptError.setTitle("Error");
enDecryptError.setResizable(true);
((Stage) enDecryptError.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Main.class.getResource("resources/cryptoGX.png").toExternalForm())); ((Stage) enDecryptError.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Main.class.getResource("resources/cryptoGX.png").toExternalForm()));
enDecryptError.getDialogPane().setContent(new Label("Error: " + throwable));
Scene window = enDecryptError.getDialogPane().getScene(); Scene window = enDecryptError.getDialogPane().getScene();
@ -275,9 +223,7 @@ public class Main extends Application {
"\nError: " + error, ButtonType.OK); "\nError: " + error, ButtonType.OK);
enDecryptError.initStyle(StageStyle.UNDECORATED); enDecryptError.initStyle(StageStyle.UNDECORATED);
enDecryptError.setTitle("Error"); enDecryptError.setTitle("Error");
enDecryptError.setResizable(true);
((Stage) enDecryptError.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Main.class.getResource("resources/cryptoGX.png").toExternalForm())); ((Stage) enDecryptError.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Main.class.getResource("resources/cryptoGX.png").toExternalForm()));
enDecryptError.getDialogPane().setContent(new Label(message));
Scene window = enDecryptError.getDialogPane().getScene(); Scene window = enDecryptError.getDialogPane().getScene();
@ -297,8 +243,6 @@ public class Main extends Application {
* <p>Shows an warning alert window</p> * <p>Shows an warning alert window</p>
* *
* @param message that the alert window will show * @param message that the alert window will show
*
* @since 1.4.0
*/ */
protected static void warningAlert(String message) { protected static void warningAlert(String message) {
AtomicReference<Double> alertX = new AtomicReference<>(Screen.getPrimary().getBounds().getMaxX() / 2); AtomicReference<Double> alertX = new AtomicReference<>(Screen.getPrimary().getBounds().getMaxX() / 2);
@ -308,7 +252,6 @@ public class Main extends Application {
enDecryptError.initStyle(StageStyle.UNDECORATED); enDecryptError.initStyle(StageStyle.UNDECORATED);
enDecryptError.setTitle("Error"); enDecryptError.setTitle("Error");
((Stage) enDecryptError.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Main.class.getResource("resources/cryptoGX.png").toExternalForm())); ((Stage) enDecryptError.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Main.class.getResource("resources/cryptoGX.png").toExternalForm()));
enDecryptError.getDialogPane().setContent(new Label(message));
Scene window = enDecryptError.getDialogPane().getScene(); Scene window = enDecryptError.getDialogPane().getScene();

View File

@ -0,0 +1,196 @@
package org.blueshard.cryptogx;
import java.io.*;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
public class SecureDelete {
/**
* <p>Overwrites the file {@param iterations} times at once with random bytes an delete it</p>
*
* @see SecureDelete#deleteFileAllInOne(File, int)
*/
public static boolean deleteFileAllInOne(String filename, int iterations) throws IOException, NoSuchAlgorithmException {
return deleteFileAllInOne(new File(filename), iterations);
}
/**
* <p>Overwrites the file {@param iterations} times at once with random bytes and delete it</p>
*
* @param file that should be deleted
* @param iterations how many times the file should be overwritten before it gets deleted
* @return if the file could be deleted
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public static boolean deleteFileAllInOne(File file, int iterations) throws IOException, NoSuchAlgorithmException {
long fileLength = file.length() + 1 ;
for (int i=0; i<iterations; i++) {
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
if (fileLength > 1000000000) {
int numOfByteArrays = (int) Math.ceil((double) fileLength / 1000000000);
for (int len=0; len<numOfByteArrays; len++) {
int newMaxFileSize = (int) fileLength / numOfByteArrays;
int newMinFileSize = 0;
byte[] randomBytes = new byte[new Random().nextInt(newMaxFileSize - newMinFileSize) + newMinFileSize];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
bufferedOutputStream.write(randomBytes);
}
} else {
byte[] randomBytes = new byte[new Random().nextInt((int) fileLength)];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
bufferedOutputStream.write(randomBytes);
}
bufferedOutputStream.flush();
bufferedOutputStream.close();
}
return file.delete();
}
/**
* <p>Overwrites the file {@param iterations} times at once with random bytes (minimal size {@param minFileSize}; maximal size {@param maxFileSize}) and delete it</p>
*
* @see SecureDelete#deleteFileAllInOne(String, int, long, long)
*/
public static boolean deleteFileAllInOne(String filename, int iterations, long minFileSize, long maxFileSize) throws IOException, NoSuchAlgorithmException {
return deleteFileAllInOne(new File(filename), iterations, minFileSize, maxFileSize);
}
/**
* <p>Overwrites the file {@param iterations} times at once with random bytes (minimal size {@param minFileSize}; maximal size {@param maxFileSize}) and delete it</p>
*
* @param file that should be deleted
* @param iterations how many times the file should be overwritten before it gets deleted
* @param minFileSize is the minimal file size for every {@param iterations}
* @param maxFileSize is the maximal file size for every {@param iterations}
* @return if the file could be deleted
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public static boolean deleteFileAllInOne(File file, int iterations, long minFileSize, long maxFileSize) throws IOException, NoSuchAlgorithmException {
for (int i = 0; i < iterations; i++) {
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
if (maxFileSize > 1000000000) {
int numOfByteArrays = (int) Math.ceil((double) maxFileSize / 1000000000);
for (int len = 0; len < numOfByteArrays; len++) {
int newMaxFileSize = (int) maxFileSize / numOfByteArrays;
int newMinFileSize = 0;
if (minFileSize != 0) {
newMinFileSize = (int) minFileSize / numOfByteArrays;
}
byte[] randomBytes = new byte[new Random().nextInt(newMaxFileSize - newMinFileSize) + newMinFileSize];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
bufferedOutputStream.write(randomBytes);
}
} else {
byte[] randomBytes = new byte[new Random().nextInt((int) maxFileSize - (int) minFileSize) + (int) minFileSize];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
bufferedOutputStream.write(randomBytes);
}
bufferedOutputStream.flush();
bufferedOutputStream.close();
}
return file.delete();
}
/**
* <p>Overwrites the file {@param iterations} times line by line with random bytes and delete it</p>
*
* @see SecureDelete#deleteFileLineByLine(File, int)
*/
public static boolean deleteFileLineByLine(String filename, int iterations) throws NoSuchAlgorithmException, IOException {
return deleteFileLineByLine(new File(filename), iterations);
}
/**
* <p>Overwrites the file {@param iterations} times line by line with random bytes and delete it</p>
*
* @param file that should be deleted
* @param iterations how many times the file should be overwritten before it gets deleted
* @return if the file could be deleted
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public static boolean deleteFileLineByLine(File file, int iterations) throws NoSuchAlgorithmException, IOException {
long fileLength = file.length() + 1 ;
for (int i=0; i<iterations; i++) {
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
if (fileLength > 1000000000) {
int numOfByteArrays = (int) Math.ceil((double) fileLength / 1000000000);
for (int len=0; len<numOfByteArrays; len++) {
int newMaxFileSize = (int) fileLength / numOfByteArrays;
int newMinFileSize = 0;
byte[] randomBytes = new byte[new Random().nextInt(newMaxFileSize - newMinFileSize) + newMinFileSize];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
for (byte b: randomBytes) {
bufferedOutputStream.write(b);
}
}
} else {
byte[] randomBytes = new byte[new Random().nextInt((int) fileLength)];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
for (byte b : randomBytes) {
bufferedOutputStream.write(b);
}
}
bufferedOutputStream.flush();
bufferedOutputStream.close();
}
return file.delete();
}
/**
* <p>Overwrites the file {@param iterations} times line by line with random bytes (minimal size {@param minFileSize}; maximal size {@param maxFileSize}) and delete it</p>
*/
public static boolean deleteFileLineByLine(String filename, int iterations, long minFileSize, long maxFileSize) throws NoSuchAlgorithmException, IOException {
return deleteFileLineByLine(new File(filename), iterations, minFileSize, maxFileSize);
}
/**
* <p>Overwrites the file {@param iterations} times line by line with random bytes (minimal size {@param minFileSize}; maximal size {@param maxFileSize}) and delete it</p>
*
* @param file that should be deleted
* @param iterations how many times the file should be overwritten before it gets deleted
* @param minFileSize is the minimal file size for every {@param iterations}
* @param maxFileSize is the maximal file size for every {@param iterations}
* @return if the file could be deleted
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public static boolean deleteFileLineByLine(File file, int iterations, long minFileSize, long maxFileSize) throws NoSuchAlgorithmException, IOException {
for (int i=0; i<iterations; i++) {
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
if (maxFileSize > 1000000000) {
int numOfByteArrays = (int) Math.ceil((double) maxFileSize / 1000000000);
for (int len=0; len<numOfByteArrays; len++) {
int newMaxFileSize = (int) maxFileSize / numOfByteArrays;
int newMinFileSize = 0;
if (minFileSize != 0) {
newMinFileSize = (int) minFileSize / numOfByteArrays;
}
byte[] randomBytes = new byte[new Random().nextInt(newMaxFileSize - newMinFileSize) + newMinFileSize];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
for (byte b: randomBytes) {
bufferedOutputStream.write(b);
}
}
} else {
byte[] randomBytes = new byte[new Random().nextInt((int) maxFileSize - (int) minFileSize) + (int) minFileSize];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
for (byte b : randomBytes) {
bufferedOutputStream.write(b);
}
}
bufferedOutputStream.flush();
bufferedOutputStream.close();
}
return file.delete();
}
}

View File

@ -0,0 +1,21 @@
package org.blueshard.cryptogx;
public class Utils {
/**
* <p>Checks if any character in {@param characters} appears in {@param string}</p>
*
* @param characters that should be searched in {@param string}
* @param string that should be searched for the characters
* @return if any character in {@param characters} appears in {@param string}
*/
public static boolean hasAnyCharacter(CharSequence characters, String string) {
for (char c: characters.toString().toCharArray()) {
if (string.indexOf(c) != -1) {
return true;
}
}
return false;
}
}

View File

@ -1,9 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.Accordion?>
<?import javafx.scene.image.*?> <?import javafx.scene.control.Button?>
<?import javafx.scene.layout.*?> <?import javafx.scene.control.CheckBox?>
<?import javafx.scene.text.*?> <?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Text?>
<AnchorPane fx:id="rootWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="605.0" prefWidth="320.0" style="-fx-border-color: black;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <AnchorPane fx:id="rootWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="605.0" prefWidth="320.0" style="-fx-border-color: black;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children> <children>
@ -13,8 +22,8 @@
<Image url="@close.png" /> <Image url="@close.png" />
</image> </image>
</ImageView> </ImageView>
<Text fx:id="saveSettingsText" layoutX="107.0" layoutY="46.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Save settings" textAlignment="CENTER" wrappingWidth="106.88330078125" /> <Text fx:id="saveSettingsText" layoutX="125.0" layoutY="46.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Save settings" />
<Text fx:id="nameOfSettingText" layoutX="49.0" layoutY="90.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Name of the new configuration" textAlignment="CENTER" wrappingWidth="221.84912109375" /> <Text fx:id="nameOfSettingText" layoutX="77.0" layoutY="86.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Name of the new configuration" />
<TextField fx:id="settingsNameEntry" layoutX="27.0" layoutY="101.0" prefHeight="25.0" prefWidth="264.0" /> <TextField fx:id="settingsNameEntry" layoutX="27.0" layoutY="101.0" prefHeight="25.0" prefWidth="264.0" />
<Accordion fx:id="rootAccordion" layoutX="10.0" layoutY="150.0" prefHeight="280.0" prefWidth="300.0"> <Accordion fx:id="rootAccordion" layoutX="10.0" layoutY="150.0" prefHeight="280.0" prefWidth="300.0">
<panes> <panes>
@ -60,11 +69,11 @@
<content> <content>
<AnchorPane fx:id="settingsPane" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0"> <AnchorPane fx:id="settingsPane" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children> <children>
<Text fx:id="fileOutputPathText" layoutX="10.0" layoutY="20.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Default file output path" /> <Text fx:id="fileOutputPathText" layoutX="10.0" layoutY="27.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Default file output path" />
<TextField fx:id="fileOutputPathEntry" layoutX="10.0" layoutY="29.0" prefHeight="25.0" prefWidth="280.0" /> <TextField fx:id="fileOutputPathEntry" layoutX="10.0" layoutY="41.0" prefHeight="25.0" prefWidth="280.0" />
<Button fx:id="fileOutputPathButton" layoutX="71.0" layoutY="66.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="157.0" text="Change output path" textAlignment="CENTER" /> <Button fx:id="fileOutputPathButton" layoutX="85.0" layoutY="78.0" mnemonicParsing="false" text="Change output path" />
<CheckBox fx:id="removeFromFileBoxCheckBox" layoutX="10.0" layoutY="102.0" mnemonicParsing="false" prefHeight="38.0" prefWidth="287.0" text="Remove files from filebox after en- / decryption" wrapText="true" /> <CheckBox fx:id="removeFromFileBoxCheckBox" layoutX="10.0" layoutY="121.0" mnemonicParsing="false" text="Remove files from filebox after en- / decryption" />
<CheckBox fx:id="limitNumberOfThreadsCheckBox" layoutX="10.0" layoutY="149.0" mnemonicParsing="false" text="Limit number of threads" /> <CheckBox fx:id="limitNumberOfThreadsCheckBox" layoutX="10.0" layoutY="151.0" mnemonicParsing="false" text="Limit number of threads" />
</children> </children>
</AnchorPane> </AnchorPane>
</content> </content>
@ -74,7 +83,7 @@
<CheckBox fx:id="encryptSettings" layoutX="10.0" layoutY="447.0" mnemonicParsing="false" text="Encrypt settings" /> <CheckBox fx:id="encryptSettings" layoutX="10.0" layoutY="447.0" mnemonicParsing="false" text="Encrypt settings" />
<Separator fx:id="separator1" layoutX="10.0" layoutY="474.0" prefWidth="300.0" /> <Separator fx:id="separator1" layoutX="10.0" layoutY="474.0" prefWidth="300.0" />
<PasswordField fx:id="hiddenPasswordEntry" disable="true" layoutX="10.0" layoutY="490.0" prefHeight="25.0" prefWidth="300.0" promptText="Password" /> <PasswordField fx:id="hiddenPasswordEntry" disable="true" layoutX="10.0" layoutY="490.0" prefHeight="25.0" prefWidth="300.0" promptText="Password" />
<TextField fx:id="visiblePasswordEntry" disable="true" layoutX="10.0" layoutY="490.0" prefHeight="25.0" prefWidth="300.0" promptText="Password" visible="false" /> <TextField fx:id="showedPasswordEntry" disable="true" layoutX="10.0" layoutY="490.0" prefHeight="25.0" prefWidth="300.0" promptText="Password" visible="false" />
<CheckBox fx:id="showPassword" disable="true" layoutX="10.0" layoutY="525.0" mnemonicParsing="false" text="Show password" /> <CheckBox fx:id="showPassword" disable="true" layoutX="10.0" layoutY="525.0" mnemonicParsing="false" text="Show password" />
<Separator fx:id="separator2" layoutX="10.0" layoutY="551.0" prefWidth="300.0" /> <Separator fx:id="separator2" layoutX="10.0" layoutY="551.0" prefWidth="300.0" />
<Button fx:id="saveButton" layoutX="131.0" layoutY="564.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="56.0" text="Save" /> <Button fx:id="saveButton" layoutX="131.0" layoutY="564.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="56.0" text="Save" />

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -1,9 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.Button?>
<?import javafx.scene.image.*?> <?import javafx.scene.control.MenuBar?>
<?import javafx.scene.layout.*?> <?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.text.*?> <?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Text?>
<AnchorPane fx:id="mainWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="253.0" prefWidth="254.0" style="-fx-border-color: black;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <AnchorPane fx:id="mainWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="253.0" prefWidth="254.0" style="-fx-border-color: black;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children> <children>
@ -13,12 +17,12 @@
<Image url="@close.png" /> <Image url="@close.png" />
</image> </image>
</ImageView> </ImageView>
<Text fx:id="exportSettingsText" layoutX="68.0" layoutY="49.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Export settings" textAlignment="CENTER" wrappingWidth="117.5283203125" /> <Text fx:id="exportSettingsText" layoutX="88.0" layoutY="48.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Export settings" />
<ScrollPane layoutX="7.0" layoutY="64.0" prefHeight="120.0" prefWidth="240.0"> <ScrollPane layoutX="7.0" layoutY="64.0" prefHeight="120.0" prefWidth="240.0">
<content> <content>
<VBox fx:id="settingsBox" prefHeight="118.0" prefWidth="238.0" /> <VBox fx:id="settingsBox" prefHeight="118.0" prefWidth="238.0" />
</content> </content>
</ScrollPane> </ScrollPane>
<Button fx:id="exportButton" layoutX="86.0" layoutY="203.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="82.0" text="Export..." textAlignment="CENTER" /> <Button fx:id="exportButton" layoutX="98.0" layoutY="203.0" mnemonicParsing="false" text="Export..." />
</children> </children>
</AnchorPane> </AnchorPane>

View File

@ -13,10 +13,11 @@
<Image url="@close.png" /> <Image url="@close.png" />
</image> </image>
</ImageView> </ImageView>
<Text fx:id="loadSettingsText" layoutX="68.0" layoutY="47.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Load settings" textAlignment="CENTER" wrappingWidth="107.38818359375" /> <Text fx:id="loadSettingsText" layoutX="86.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Load settings" />
<ComboBox fx:id="settingsBox" layoutX="24.0" layoutY="72.0" prefHeight="25.0" prefWidth="194.0" /> <ComboBox fx:id="settingsBox" layoutX="24.0" layoutY="72.0" prefHeight="25.0" prefWidth="194.0" />
<PasswordField fx:id="passwordEntryHide" layoutX="16.0" layoutY="118.0" prefHeight="26.0" prefWidth="211.0" promptText="Password" /> <Text fx:id="passwordText" layoutX="14.0" layoutY="136.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Password" />
<TextField fx:id="passwordEntryShow" layoutX="16.0" layoutY="118.0" prefHeight="26.0" prefWidth="211.0" visible="false" /> <PasswordField fx:id="passwordEntryHide" layoutX="79.0" layoutY="119.0" />
<TextField fx:id="passwordEntryShow" layoutX="79.0" layoutY="119.0" visible="false" />
<CheckBox fx:id="showPassword" layoutX="14.0" layoutY="154.0" mnemonicParsing="false" text="Show password" /> <CheckBox fx:id="showPassword" layoutX="14.0" layoutY="154.0" mnemonicParsing="false" text="Show password" />
<Separator fx:id="separator1" layoutX="16.0" layoutY="181.0" prefHeight="0.0" prefWidth="211.0" /> <Separator fx:id="separator1" layoutX="16.0" layoutY="181.0" prefHeight="0.0" prefWidth="211.0" />
<Button fx:id="loadButton" layoutX="29.0" layoutY="193.0" mnemonicParsing="false" text="Load" /> <Button fx:id="loadButton" layoutX="29.0" layoutY="193.0" mnemonicParsing="false" text="Load" />

View File

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@ -1,12 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?> <?import javafx.scene.control.Button?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.ComboBox?>
<?import javafx.scene.image.*?> <?import javafx.scene.control.Menu?>
<?import javafx.scene.layout.*?> <?import javafx.scene.control.MenuBar?>
<?import javafx.scene.text.*?> <?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.RadioMenuItem?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Text?>
<AnchorPane fx:id="rootWindow" prefHeight="470.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.bytedream.cryptogx.Controller"> <AnchorPane fx:id="rootWindow" prefHeight="470.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.blueshard.cryptogx.Controller">
<children> <children>
<MenuBar fx:id="menubar" prefHeight="25.0" prefWidth="900.0"> <MenuBar fx:id="menubar" prefHeight="25.0" prefWidth="900.0">
<menus> <menus>
@ -37,62 +48,56 @@
<image> <image>
<Image url="@close.png" /> <Image url="@close.png" />
</image></ImageView> </image></ImageView>
<Text fx:id="textText" layoutX="81.0" layoutY="49.0" strokeType="OUTSIDE" strokeWidth="0.0" text="En- / decrypt Text" textAlignment="CENTER" wrappingWidth="135.9" /> <Text fx:id="textText" layoutX="103.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="En- / decrypt Text" />
<TextField fx:id="textKeyEntry" layoutX="74.0" layoutY="64.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="155.0" promptText="Key" /> <TextField fx:id="textKeyEntry" layoutX="76.0" layoutY="64.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" promptText="Key" />
<TextArea fx:id="textDecryptedEntry" layoutX="7.0" layoutY="107.0" onKeyTyped="#keyTypedTooltip" prefHeight="105.0" prefWidth="286.0" promptText="Decrypted Text" /> <TextArea fx:id="textDecryptedEntry" layoutX="7.0" layoutY="107.0" onKeyTyped="#keyTypedTooltip" prefHeight="105.0" prefWidth="286.0" promptText="Decrypted Text" />
<TextArea fx:id="textEncryptedEntry" layoutX="7.0" layoutY="222.0" onKeyTyped="#keyTypedTooltip" prefHeight="105.0" prefWidth="286.0" promptText="Encrypted Text" /> <TextArea fx:id="textEncryptedEntry" layoutX="7.0" layoutY="222.0" onKeyTyped="#keyTypedTooltip" prefHeight="105.0" prefWidth="286.0" promptText="Encrypted Text" />
<Button fx:id="textEncryptButton" layoutX="29.0" layoutY="339.0" mnemonicParsing="false" onAction="#textEncryptButton" prefHeight="26.0" prefWidth="76.0" text="Encrypt" /> <Button fx:id="textEncryptButton" layoutX="47.0" layoutY="339.0" mnemonicParsing="false" onAction="#textEncryptButton" text="Encrypt" />
<ImageView fx:id="textLoadingImage" fitHeight="40.0" fitWidth="40.0" layoutX="131.0" layoutY="332.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="textLoadingImage" fitHeight="40.0" fitWidth="40.0" layoutX="131.0" layoutY="332.0" pickOnBounds="true" preserveRatio="true" />
<Button fx:id="textDecryptButton" layoutX="199.0" layoutY="340.0" mnemonicParsing="false" onAction="#textDecryptButton" prefHeight="26.0" prefWidth="76.0" text="Decrypt" /> <Button fx:id="textDecryptButton" layoutX="199.0" layoutY="340.0" mnemonicParsing="false" onAction="#textDecryptButton" text="Decrypt" />
<Separator fx:id="textSeparator1" layoutX="7.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" /> <Separator fx:id="textSeparator1" layoutX="7.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
<Text fx:id="textAdvanced" layoutX="106.0" layoutY="386.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" textAlignment="CENTER" wrappingWidth="85.9" /> <Text fx:id="textAdvanced" layoutX="124.0" layoutY="386.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" wrappingWidth="53.701171875" />
<Separator fx:id="textSeparator2" layoutX="190.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" /> <Separator fx:id="textSeparator2" layoutX="187.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
<Text fx:id="textAlgorithm" layoutX="185.0" layoutY="409.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" textAlignment="CENTER" wrappingWidth="77.6" /> <Text fx:id="textAlgorithm" layoutX="194.0" layoutY="409.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" />
<TextField fx:id="textSaltEntry" layoutX="14.0" layoutY="419.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="136.0" promptText="Salt" /> <TextField fx:id="textSaltEntry" layoutX="14.0" layoutY="419.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="136.0" promptText="Salt" />
<ComboBox fx:id="textAlgorithmBox" layoutX="156.0" layoutY="419.0" prefHeight="25.0" prefWidth="136.0" /> <ComboBox fx:id="textAlgorithmBox" layoutX="156.0" layoutY="419.0" prefHeight="25.0" prefWidth="136.0" />
<Separator fx:id="midSeparator1" layoutX="300.0" layoutY="35.0" orientation="VERTICAL" prefHeight="424.0" prefWidth="0.0" /> <Separator fx:id="midSeparator1" layoutX="300.0" layoutY="35.0" orientation="VERTICAL" prefHeight="424.0" prefWidth="0.0" />
<Text fx:id="fileEnDecryptText" layoutX="384.0" layoutY="49.0" strokeType="OUTSIDE" strokeWidth="0.0" text="En- / decrypt Files" textAlignment="CENTER" wrappingWidth="135.9" /> <Text fx:id="fileEnDecryptText" layoutX="403.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="En- / decrypt Files" />
<TextField fx:id="fileEnDecryptKeyEntry" layoutX="374.0" layoutY="64.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="155.0" promptText="Key" /> <TextField fx:id="fileEnDecryptKeyEntry" layoutX="376.0" layoutY="64.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" promptText="Key" />
<Button fx:id="fileEnDecryptFilesButton" layoutX="316.0" layoutY="97.0" mnemonicParsing="false" onAction="#fileEnDecryptChooseFiles" prefHeight="26.0" prefWidth="120.0" text="Choose files..." /> <Button fx:id="fileEnDecryptFilesButton" layoutX="408.0" layoutY="97.0" mnemonicParsing="false" onAction="#fileEnDecryptChoose" text="Choose files..." />
<Text layoutX="445.0" layoutY="114.0" scaleX="1.7" scaleY="1.7" scaleZ="1.7" strokeType="OUTSIDE" strokeWidth="0.0" text="/" textAlignment="CENTER" wrappingWidth="12.111118853092194" />
<Button fx:id="fileEnDecryptDirectoriesButton" layoutX="467.0" layoutY="97.0" mnemonicParsing="false" onAction="#fileEnDecryptChooseDirectories" prefHeight="26.0" prefWidth="120.0" text="directories..." />
<ScrollPane fx:id="fileEnDecryptInputScroll" hbarPolicy="NEVER" layoutX="309.0" layoutY="130.0" onKeyPressed="#onFileEnDecryptPaste" prefHeight="107.0" prefWidth="286.0"> <ScrollPane fx:id="fileEnDecryptInputScroll" hbarPolicy="NEVER" layoutX="309.0" layoutY="130.0" onKeyPressed="#onFileEnDecryptPaste" prefHeight="107.0" prefWidth="286.0">
<content> <content>
<VBox fx:id="fileEnDecryptInputFiles" onDragDropped="#onFileEnDecryptDragNDrop" onDragOver="#onFileEnDecryptDragOver" prefHeight="105.0" prefWidth="282.0" /> <VBox fx:id="fileEnDecryptInputFiles" onDragDropped="#onFileEnDecryptDragNDrop" onDragOver="#onFileEnDecryptDragOver" prefHeight="105.0" prefWidth="282.0" />
</content> </content>
</ScrollPane> </ScrollPane>
<TextField fx:id="fileEncryptOutputFile" editable="false" layoutX="310.0" layoutY="245.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="26.0" prefWidth="286.0" promptText="Encrypted File" /> <Text fx:id="fileEncryptOutputFileText" layoutX="310.0" layoutY="261.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Encrypted File" />
<TextField fx:id="fileDecryptOutputFile" editable="false" layoutX="310.0" layoutY="277.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="27.0" prefWidth="286.0" promptText="Decrypted File" /> <TextField fx:id="fileEncryptOutputFile" editable="false" layoutX="390.0" layoutY="244.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="201.0" />
<Button fx:id="fileEncrypt" layoutX="329.0" layoutY="314.0" mnemonicParsing="false" onAction="#fileEncryptButton" prefHeight="26.0" prefWidth="76.0" text="Encrypt" /> <Text fx:id="fileDecryptOutputFileText" layoutX="310.0" layoutY="290.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Decrypted File" />
<TextField fx:id="fileDecryptOutputFile" editable="false" layoutX="390.0" layoutY="273.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="201.0" />
<Button fx:id="fileEncrypt" layoutX="347.0" layoutY="313.0" mnemonicParsing="false" onAction="#fileEncryptButton" text="Encrypt" />
<ImageView fx:id="fileEnDecryptLoadingImage" fitHeight="40.0" fitWidth="40.0" layoutX="432.0" layoutY="306.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="fileEnDecryptLoadingImage" fitHeight="40.0" fitWidth="40.0" layoutX="432.0" layoutY="306.0" pickOnBounds="true" preserveRatio="true" />
<Button fx:id="fileDecrypt" layoutX="499.0" layoutY="314.0" mnemonicParsing="false" onAction="#fileDecryptButton" prefHeight="26.0" prefWidth="76.0" text="Decrypt" /> <Button fx:id="fileDecrypt" layoutX="499.0" layoutY="313.0" mnemonicParsing="false" onAction="#fileDecryptButton" text="Decrypt" />
<Button fx:id="fileEnDecryptStop" layoutX="417.0" layoutY="345.0" mnemonicParsing="false" onAction="#fileEnDecryptCancelButton" prefHeight="26.0" prefWidth="68.0" text="Cancel" /> <Button fx:id="fileEnDecryptStop" layoutX="426.0" layoutY="346.0" mnemonicParsing="false" onAction="#fileEnDecryptCancelButton" text="Cancel" />
<Separator fx:id="fileEnDecryptSeparator1" layoutX="309.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" /> <Separator fx:id="fileEnDecryptSeparator1" layoutX="309.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
<Text fx:id="fileEnDecryptAdvanced" layoutX="409.0" layoutY="387.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" textAlignment="CENTER" wrappingWidth="85.9" /> <Text fx:id="fileEnDecryptAdvanced" layoutX="426.0" layoutY="386.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" wrappingWidth="53.701171875" />
<Separator fx:id="fileEnDecryptSeparator2" layoutX="489.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" /> <Separator fx:id="fileEnDecryptSeparator2" layoutX="485.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
<Text fx:id="fileEnDecryptAlgorithm" layoutX="484.0" layoutY="409.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" textAlignment="CENTER" wrappingWidth="77.6" /> <Text fx:id="fileEnDecryptAlgorithm" layoutX="494.0" layoutY="409.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" />
<TextField fx:id="fileEnDecryptSaltEntry" layoutX="311.0" layoutY="419.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="136.0" promptText="Salt" /> <TextField fx:id="fileEnDecryptSaltEntry" layoutX="311.0" layoutY="419.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="136.0" promptText="Salt" />
<ComboBox fx:id="fileEnDecryptAlgorithmBox" layoutX="455.0" layoutY="419.0" prefHeight="25.0" prefWidth="136.0" /> <ComboBox fx:id="fileEnDecryptAlgorithmBox" layoutX="455.0" layoutY="419.0" prefHeight="25.0" prefWidth="136.0" />
<Separator fx:id="midSeparator2" layoutX="600.0" layoutY="35.0" orientation="VERTICAL" prefHeight="424.0" prefWidth="0.0" /> <Separator fx:id="midSeparator2" layoutX="600.0" layoutY="35.0" orientation="VERTICAL" prefHeight="424.0" prefWidth="0.0" />
<Text fx:id="fileDeleteText" layoutX="684.0" layoutY="49.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Secure delete files" textAlignment="CENTER" wrappingWidth="135.9" /> <Text fx:id="fileDeleteText" layoutX="703.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Secure delete files" />
<Button fx:id="fileDeleteChooseFilesButton" layoutX="616.0" layoutY="64.0" mnemonicParsing="false" onAction="#fileDeleteChooseFiles" prefHeight="26.0" prefWidth="120.0" text="Choose files..." /> <Button fx:id="fileEnDecryptFilesButton1" layoutX="708.0" layoutY="64.0" mnemonicParsing="false" onAction="#fileDeleteChoose" text="Choose files..." />
<Text layoutX="744.0" layoutY="81.0" scaleX="1.7" scaleY="1.7" scaleZ="1.7" strokeType="OUTSIDE" strokeWidth="0.0" text="/" textAlignment="CENTER" wrappingWidth="12.111118853092194" /> <ScrollPane fx:id="fileDeleteInputScroll" hbarPolicy="NEVER" layoutX="608.0" layoutY="96.0" prefHeight="228.0" prefWidth="285.0">
<Button fx:id="fileDeleteChooseDirectoriesButton" layoutX="764.0" layoutY="64.0" mnemonicParsing="false" onAction="#fileDeleteChooseDirectories" prefHeight="26.0" prefWidth="120.0" text="directories..." />
<ScrollPane fx:id="fileDeleteInputScroll" hbarPolicy="NEVER" layoutX="608.0" layoutY="100.0" prefHeight="228.0" prefWidth="285.0">
<content> <content>
<VBox fx:id="fileDeleteInputFiles" onDragDropped="#onFileDeleteDragNDrop" onDragOver="#onFileDeleteDragOver" prefHeight="226.0" prefWidth="283.0" /> <VBox fx:id="fileDeleteInputFiles" onDragDropped="#onFileDeleteDragNDrop" onDragOver="#onFileDeleteDragOver" prefHeight="226.0" prefWidth="282.0" />
</content> </content>
</ScrollPane> </ScrollPane>
<Button fx:id="fileDeleteButton" layoutX="646.0" layoutY="339.0" mnemonicParsing="false" onAction="#fileDelete" prefWidth="68.0" text="Delete" /> <Button fx:id="fileDeleteButton" layoutX="647.0" layoutY="339.0" mnemonicParsing="false" onAction="#fileDelete" text="Delete" />
<ImageView fx:id="fileDeleteLoadingImage" fitHeight="40.0" fitWidth="40.0" layoutX="729.0" layoutY="332.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="fileDeleteLoadingImage" fitHeight="40.0" fitWidth="40.0" layoutX="729.0" layoutY="332.0" pickOnBounds="true" preserveRatio="true" />
<Button fx:id="fileDeleteStop" layoutX="796.0" layoutY="339.0" mnemonicParsing="false" onAction="#fileDeleteCancelButton" prefWidth="68.0" text="Cancel" /> <Button fx:id="fileDeleteStop" layoutX="799.0" layoutY="339.0" mnemonicParsing="false" onAction="#fileDeleteCancelButton" text="Cancel" />
<Separator fx:id="fileDeleteSeparator1" layoutX="610.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" /> <Separator fx:id="fileDeleteSeparator1" layoutX="610.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
<Text fx:id="fileDeleteAdvanced" layoutX="709.0" layoutY="387.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" textAlignment="CENTER" wrappingWidth="85.9" /> <Text fx:id="fileDeleteAdvanced" layoutX="725.0" layoutY="386.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" wrappingWidth="53.015625" />
<Separator fx:id="fileDeleteSeparator2" layoutX="791.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" /> <Separator fx:id="fileDeleteSeparator2" layoutX="781.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
<TextField fx:id="fileDeleteIterationsEntry" layoutX="684.0" layoutY="419.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="136.0" promptText="Iterations" text="5" /> <TextField fx:id="fileDeleteIterationsEntry" layoutX="684.0" layoutY="419.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="136.0" promptText="Iterations" text="5" />
<Text fx:id="version" fill="#0000006a" layoutX="-6.0" layoutY="465.0" scaleX="0.7" scaleY="0.7" strokeType="OUTSIDE" strokeWidth="0.0" text="v1.12.0" wrappingWidth="57.999987464019796">
<rotationAxis>
<Point3D />
</rotationAxis></Text>
</children> </children>
</AnchorPane> </AnchorPane>

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,302 +0,0 @@
package org.bytedream.cryptogx;
import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* <p>Class for en- / decrypt text and files<p/>
*
* @since 1.0.0
*/
public class EnDecrypt {
public static class AES extends Thread {
public int iterations = 65536;
private final String secretKeyFactoryAlgorithm = "PBKDF2WithHmacSHA1";
private int keySize = 256;
private final String key;
private final byte[] salt;
public AES(String key, byte[] salt) {
this.key = key;
this.salt = salt;
}
public AES(String key, byte[] salt, int keySize) {
this.key = key;
this.salt = salt;
this.keySize = keySize;
}
public AES(String key, byte[] salt, int iterations, int keySize) {
this.key = key;
this.salt = salt;
this.iterations = iterations;
this.keySize = keySize;
}
/**
* <p>Creates a secret key from given (plain text) key and salt</p>
*
* @return the secret key
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*
* @since 1.0.0
*/
private byte[] createSecretKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
SecretKeyFactory factory = SecretKeyFactory.getInstance(secretKeyFactoryAlgorithm);
PBEKeySpec keySpec = new PBEKeySpec(key.toCharArray(), salt, iterations, keySize);
return factory.generateSecret(keySpec).getEncoded();
}
/**
* <p>Writes {@param inputStream} to {@param outputStream}</p>
*
* @param inputStream from which is written
* @param outputStream to which is written
* @param buffer
* @throws IOException
*
* @since 1.12.0
*/
private void write(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws IOException {
int numOfBytesRead;
while ((numOfBytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, numOfBytesRead);
}
outputStream.close();
inputStream.close();
}
/**
* <p>Encrypts the {@param inputStream} to {@param outputStream}</p>
*
* @param inputStream that should be encrypted
* @param outputStream to which the encrypted {@param inputFile} should be written to
* @param buffer
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
*
* @since 1.12.0
*/
public void encryptFile(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException {
Key secretKey = new SecretKeySpec(createSecretKey(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
write(cipherInputStream, outputStream, buffer);
}
/**
* <p>Encrypts all files in the {@param inputDirectory} to the {@param outputDirectory}</p>
*
* @param inputDirectory that should be encrypted
* @param outputDirectory to which the encrypted {@param inputDirectory} files should be written to
* @param fileEnding get added to every file that gets encrypted (if the {@param fileEnding} starts and ends with
* a '@', the {@param fileEnding} will get removed from the file if it exists)
* @param buffer
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
*
* @since 1.12.0
*/
public void encryptDirectory(String inputDirectory, String outputDirectory, String fileEnding, byte[] buffer) throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException {
AtomicBoolean remove = new AtomicBoolean(false);
if (fileEnding == null) {
fileEnding = "";
} else if (fileEnding.startsWith("@") && fileEnding.endsWith("@")) {
fileEnding = fileEnding.substring(1, fileEnding.length() - 1);
remove.set(true);
}
HashMap<File, File> files = new HashMap<>();
final String finalFileEnding = fileEnding;
Files.walk(Paths.get(inputDirectory)).map(Path::toFile).forEach(oldFile -> {
String oldFilePath = oldFile.getAbsolutePath();
if (oldFile.isDirectory()) {
new File(oldFilePath.replace(inputDirectory, outputDirectory + "/")).mkdir();
}else if (remove.get() && oldFilePath.endsWith(finalFileEnding)) {
files.put(oldFile, new File(oldFilePath.substring(0, oldFilePath.lastIndexOf(finalFileEnding))
.replace(inputDirectory, outputDirectory + "/") + finalFileEnding));
} else {
files.put(oldFile, new File(oldFilePath.replace(inputDirectory, outputDirectory + "/") + finalFileEnding));
}
});
File newFile;
for (Map.Entry<File, File> entry: files.entrySet()) {
newFile = entry.getValue();
encryptFile(new FileInputStream(entry.getKey()), new FileOutputStream(newFile), buffer);
}
}
/**
* <p>Decrypts the {@param inputStream} to {@param outputStream}</p>
*
* @param inputStream that should be decrypted
* @param outputStream to which the decrypted {@param inputFile} should be written to
* @param buffer
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
* @throws InvalidAlgorithmParameterException
*
* @since 1.12.0
*/
public void decryptFile(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException{
Key secretKey = new SecretKeySpec(createSecretKey(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher);
write(inputStream, cipherOutputStream, buffer);
}
/**
* <p>Decrypts all files in the {@param inputDirectory} to the {@param outputDirectory}</p>
*
* @param inputDirectory that should be decrypted
* @param outputDirectory to which the decrypted {@param inputDirectory} files should be written to
* @param fileEnding get added to every file that gets decrypted (if the {@param fileEnding} starts and ends with
* a '@', the {@param fileEnding} will get removed from the file if it exists)
* @param buffer
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
*
* @since 1.12.0
*/
public void decryptDirectory(String inputDirectory, String outputDirectory, String fileEnding, byte[] buffer) throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException {
AtomicBoolean remove = new AtomicBoolean(false);
if (fileEnding == null) {
fileEnding = "";
} else if (fileEnding.startsWith("@") && fileEnding.endsWith("@")) {
fileEnding = fileEnding.substring(1, fileEnding.length() - 1);
remove.set(true);
}
HashMap<File, File> files = new HashMap<>();
final String finalFileEnding = fileEnding;
Files.walk(Paths.get(inputDirectory)).map(Path::toFile).forEach(oldFile -> {
String oldFilePath = oldFile.getAbsolutePath();
if (oldFile.isDirectory()) {
new File(oldFilePath.replace(inputDirectory, outputDirectory + "/")).mkdir();
}
else if (remove.get() && oldFilePath.endsWith(finalFileEnding)) {
files.put(oldFile, new File(oldFilePath.substring(0, oldFilePath.lastIndexOf(finalFileEnding))
.replace(inputDirectory, outputDirectory + "/") + finalFileEnding));
} else {
files.put(oldFile, new File(oldFilePath.replace(inputDirectory, outputDirectory + "/") + finalFileEnding));
}
});
File newFile;
for (Map.Entry<File, File> entry: files.entrySet()) {
newFile = entry.getValue();
decryptFile(new FileInputStream(entry.getKey()), new FileOutputStream(newFile), buffer);
}
}
/**
* <p>Encrypt {@param bytes}</p>
*
* @param bytes that should be encrypted
* @return encrypted bytes
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
*
* @since 1.0.0
*/
public byte[] encrypt(byte[] bytes) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
Key secretKey = new SecretKeySpec(createSecretKey(), "AES");
Cipher encryptCipher = Cipher.getInstance("AES");
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
return encryptCipher.doFinal(bytes);
}
/**
* <p>Encrypt {@param bytes}</p>
*
* @param string that should be encrypted
*
* @see EnDecrypt.AES#encrypt(byte[])
*
* @since 1.0.0
*/
public String encrypt(String string) throws BadPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException {
return Base64.getEncoder().encodeToString(encrypt(string.getBytes(StandardCharsets.UTF_8)));
}
/**
* <p>Decrypt encrypted {@param bytes}</p>
*
* @param bytes that should be decrypted
* @return decrypted bytes
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
*
* @since 1.12.0
*/
public byte[] decrypt(byte[] bytes) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
Key secretKey = new SecretKeySpec(createSecretKey(), "AES");
Cipher decryptCipher = Cipher.getInstance("AES");
decryptCipher.init(Cipher.DECRYPT_MODE, secretKey);
return decryptCipher.doFinal(Base64.getDecoder().decode(bytes));
}
/**
* <p>Decrypt encrypted {@param string}</p>
*
* @param string that should be decrypted
*
* @see EnDecrypt.AES#decrypt(byte[])
*
* @since 1.0.0
*/
public String decrypt(String string) throws BadPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException {
return new String(decrypt(string.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
}
}
}

View File

@ -1,90 +0,0 @@
package org.bytedream.cryptogx;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
import java.util.TreeSet;
/**
* <p>Class for secure delete files<p/>
*
* @since 1.2.0
*/
public class SecureDelete {
public static void deleteDirectory(String directory, int iterations, byte[] buffer) throws IOException {
TreeSet<File> directories = new TreeSet<>();
Files.walk(Paths.get(directory)).map(Path::toFile).forEach(directoryFile -> {
if (directoryFile.isDirectory()) {
directories.add(directoryFile);
} else {
try {
SecureDelete.deleteFile(directoryFile, iterations, buffer);
} catch (IOException e) {
e.printStackTrace();
}
while (directoryFile.exists()) {
if (directoryFile.delete()) {
break;
}
}
}
});
File deleteDirectory = directories.last();
while (deleteDirectory != null) {
deleteDirectory.delete();
while (deleteDirectory.delete()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
deleteDirectory = directories.lower(deleteDirectory);
}
}
/**
* <p>Overwrites the file {@param iterations} times line by line with random bytes (minimal size {@param minFileSize}; maximal size {@param maxFileSize}) and delete it</p>
*
* @param file that should be deleted
* @param iterations how many times the file should be overwritten before it gets deleted
* @return if the file could be deleted
* @throws IOException
*
* @since 1.12.0
*/
public static void deleteFile(File file, int iterations, byte[] buffer) throws IOException {
SecureRandom secureRandom = new SecureRandom();
RandomAccessFile raf = new RandomAccessFile(file, "rws");
for (int i=0; i<iterations; i++) {
long length = file.length();
raf.seek(0);
raf.getFilePointer();
int pos = 0;
while (pos < length) {
secureRandom.nextBytes(buffer);
raf.write(buffer);
pos += buffer.length;
}
}
raf.close();
while (file.delete()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

View File

@ -1,51 +0,0 @@
package org.bytedream.cryptogx;
import java.util.TreeMap;
/**
* <p>Support class<p/>
*
* @since 1.3.0
*/
public class Utils {
public static TreeMap<String, String> algorithms = allAlgorithms();
/**
* <p>Get all available algorithms</p>
*
* @return all available algorithms
*
* @since 1.12.0
*/
private static TreeMap<String, String> allAlgorithms() {
TreeMap<String, String> return_map = new TreeMap<>();
int[] aesKeySizes = {128, 192, 256};
for (int i: aesKeySizes) {
return_map.put("AES-" + i, "AES");
}
return return_map;
}
/**
* <p>Checks if any character in {@param characters} appears in {@param string}</p>
*
* @param characters that should be searched in {@param string}
* @param string that should be searched for the characters
* @return if any character in {@param characters} appears in {@param string}
*
* @since 1.3.0
*/
public static boolean hasAnyCharacter(CharSequence characters, String string) {
for (char c: characters.toString().toCharArray()) {
if (string.indexOf(c) != -1) {
return false;
}
}
return true;
}
}