Compare commits
44 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
58b91da0dd | ||
|
e0f1b579f5 | ||
|
4e1fc596e4 | ||
|
95a8edf6e9 | ||
|
aeacde432c | ||
|
fc88d83610 | ||
|
543a1c5eff | ||
|
8279aacd07 | ||
|
50e49a838d | ||
|
a2530fd971 | ||
|
4a9e5ee404 | ||
|
9afe7c90e4 | ||
|
55f2784ba0 | ||
|
31bf88df1c | ||
|
961cce67fb | ||
|
1d33e76c69 | ||
|
b0f6051ece | ||
|
3c8697cf7d | ||
|
d0c088e7d6 | ||
|
39fd46dfa2 | ||
|
66be1c76c5 | ||
|
12d4538c68 | ||
|
94cf6b1e65 | ||
|
08537982ff | ||
|
7cdfa47a4e | ||
|
1944cb35f9 | ||
|
9e822604de | ||
|
7c6cc5161e | ||
|
d9b8de8261 | ||
|
9a55dfc3df | ||
|
b5ab29fa82 | ||
|
375fd98ec8 | ||
|
e3057a3262 | ||
|
5e6b863b11 | ||
|
4f83106d0a | ||
|
92a7dea2e4 | ||
|
4b5b951b7b | ||
|
2f47c7c1de | ||
|
49005be860 | ||
|
d4eeb6582b | ||
|
77183e2cd2 | ||
|
512eaf622f | ||
|
064cbeaf7f | ||
|
cc84a27eb4 |
@ -1,3 +0,0 @@
|
||||
### Version 1.11.0 / 04.05.2020
|
||||
|
||||
CryptoGX was uploaded for the first time on github
|
26
README.md
@ -1,3 +1,5 @@
|
||||
**please just use another encryption software which works correctly and has better en-/decoding options**
|
||||
|
||||
**_cryptoGX_** - just another en- / decryption software
|
||||
|
||||
- [Introduction](#introduction)
|
||||
@ -10,16 +12,20 @@
|
||||
**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.
|
||||
|
||||
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).
|
||||
Because the GUI uses javaFX, java version from 1.8.0_40 to 10.* with javaFX support is required.
|
||||
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
|
||||
|
||||
| 1.11.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) |
|
||||
| [Windows portable](https://dl.dropbox.com/s/10jf6cfpnejrvbf/cryptoGX_1.11.0_portable.exe?dl=0) |
|
||||
| [Windows installer](https://dl.dropbox.com/s/lq9kuv4erv39y3n/cryptoGX_1.11.0_win_setup.exe?dl=0) |
|
||||
### [All releases](#https://github.com/blueShard-dev/cryptoGX/releases/)
|
||||
|
||||
| Latest release (1.12.0) |
|
||||
|:------------------------|
|
||||
| [Source code](https://github.com/blueShard-dev/cryptoGX/archive/v1.12.0.zip) |
|
||||
| [Executable jar file](https://github.com/blueShard-dev/cryptoGX/releases/download/v1.12.0/cryptoGX.jar) |
|
||||
| [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)
|
||||
|
||||
@ -41,10 +47,10 @@ Usage AES:
|
||||
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>
|
||||
|
||||
Secure delete file: <iterations> <path of file to delete>
|
||||
File secure delete: <cryptoGX jar file> delete <iterations> <path of file to delete> //for <iterations> the argument 'default' can be used, which is 5
|
||||
```
|
||||
or type `<cryptoGX jar file> -help` to get help
|
||||
or type `<cryptoGX jar file> help` to get help
|
||||
|
||||
# License
|
||||
|
||||
This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for more details
|
||||
This project is licensed under the Mozilla Public Licence 2.0 - see the [LICENSE](LICENSE) file for more details
|
||||
|
@ -1,531 +0,0 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,196 +0,0 @@
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.blueshard.cryptogx;
|
||||
package org.bytedream.cryptogx;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
@ -35,6 +35,10 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
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.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -43,8 +47,8 @@ import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.blueshard.cryptogx.Config.*;
|
||||
import static org.blueshard.cryptogx.Main.*;
|
||||
import static org.bytedream.cryptogx.Settings.*;
|
||||
import static org.bytedream.cryptogx.Main.*;
|
||||
|
||||
public class Controller implements Initializable {
|
||||
|
||||
@ -54,35 +58,33 @@ public class Controller implements Initializable {
|
||||
private boolean textLoading = false;
|
||||
private boolean fileEnDecryptLoading = false;
|
||||
private boolean fileDeleteLoading = false;
|
||||
private AtomicInteger textThreads = new AtomicInteger(0);
|
||||
private AtomicInteger totalThreads = new AtomicInteger(0);
|
||||
private int tooltipShow = 15;
|
||||
private final AtomicInteger textThreads = new AtomicInteger(0);
|
||||
private final AtomicInteger totalThreads = new AtomicInteger(0);
|
||||
private final int tooltipShow = 15;
|
||||
private final int DATAFILEURL = 2;
|
||||
private final int FILEFILEURL = 1;
|
||||
private final int NONSPECIFICFILEURL = 0;
|
||||
private final int IMAGE = 78345;
|
||||
private final int FILE = 23902;
|
||||
private final int UNKNOWN = 12345;
|
||||
private final byte[] buffer = new byte[64];
|
||||
private final KeyCombination paste = new KeyCodeCombination(KeyCode.V, KeyCombination.CONTROL_DOWN);
|
||||
private final Image loadingImage = new Image(getClass().getResource("resources/loading.gif").toExternalForm());
|
||||
|
||||
private HashMap<String, String> currentConfigSettings = new HashMap<>();
|
||||
|
||||
private HashMap<Label, ArrayList<File>> enDecryptInputOutputFiles = new HashMap<>();
|
||||
private HashMap<Label, ArrayList<Object>> enDecryptInputOutputInternetFiles = new HashMap<>();
|
||||
private HashMap<Label, BufferedImage> enDecryptInputOutputClipboardImages = new HashMap<>();
|
||||
private HashMap<Label, File> deleteInputFiles = new HashMap<>();
|
||||
private List<Thread> fileEnDecryptThreads = Collections.synchronizedList(new ArrayList<>());
|
||||
private List<Thread> fileDeleteThreads = Collections.synchronizedList(new ArrayList<>());
|
||||
private final HashMap<Label, ArrayList<File>> enDecryptInputOutputFiles = new HashMap<>();
|
||||
private final HashMap<Label, ArrayList<Object>> enDecryptInputOutputInternetFiles = new HashMap<>();
|
||||
private final HashMap<Label, BufferedImage> enDecryptInputOutputClipboardImages = new HashMap<>();
|
||||
private final HashMap<Label, File> deleteInputFiles = new HashMap<>();
|
||||
private final List<Thread> fileEnDecryptThreads = Collections.synchronizedList(new ArrayList<>());
|
||||
private final List<Thread> fileDeleteThreads = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
private ContextMenu fileEnDecryptInputContextMenu = new ContextMenu();
|
||||
private ContextMenu fileDeleteInputContextMenu = new ContextMenu();
|
||||
private final ContextMenu fileEnDecryptInputContextMenu = new ContextMenu();
|
||||
private final ContextMenu fileDeleteInputContextMenu = new ContextMenu();
|
||||
private Label choosedLabel = null;
|
||||
private String choosedLabelType = null;
|
||||
private MenuItem fileOutputFileChangeDest = new MenuItem("Change output file");
|
||||
private MenuItem getChoosedLabelInputFileFolder = new MenuItem("Open source directory");
|
||||
private MenuItem getChoosedLabelOutputFileFolder = new MenuItem("Open source directory");
|
||||
private Tooltip tooltip = new Tooltip();
|
||||
private final MenuItem fileOutputFileChangeDest = new MenuItem("Change output file");
|
||||
private final MenuItem getChoosedLabelInputFileFolder = new MenuItem("Open source directory");
|
||||
private final MenuItem getChoosedLabelOutputFileFolder = new MenuItem("Open source directory");
|
||||
private final Tooltip tooltip = new Tooltip();
|
||||
|
||||
public AnchorPane rootWindow;
|
||||
|
||||
@ -101,6 +103,7 @@ public class Controller implements Initializable {
|
||||
public ImageView fileDeleteLoadingImage;
|
||||
|
||||
public Menu settingsMenu;
|
||||
public Menu helpMenu;
|
||||
|
||||
public MenuBar menubar;
|
||||
|
||||
@ -194,11 +197,13 @@ public class Controller implements Initializable {
|
||||
tooltip.hide();
|
||||
}
|
||||
|
||||
//-----root-----//
|
||||
//-----menu / close bar-----//
|
||||
|
||||
/**
|
||||
* <p>Closed the application.
|
||||
* Get called if red close button is pressed</p>
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public void closeApplication() {
|
||||
Stage rootStage = (Stage) rootWindow.getScene().getWindow();
|
||||
@ -209,6 +214,8 @@ public class Controller implements Initializable {
|
||||
/**
|
||||
* <p>Hides the application.
|
||||
* Get called if the green minimize button is pressed</p>
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public void minimizeApplication() {
|
||||
Stage rootStage = (Stage) rootWindow.getScene().getWindow();
|
||||
@ -220,6 +227,8 @@ public class Controller implements Initializable {
|
||||
/**
|
||||
* <p>Encrypt text in {@link Controller#textDecryptedEntry}.
|
||||
* Get called if the text 'Encrypt' button is pressed</p>
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public void textEncryptButton() {
|
||||
final byte[] salt;
|
||||
@ -243,12 +252,11 @@ public class Controller implements Initializable {
|
||||
}
|
||||
}
|
||||
totalThreads.getAndIncrement();
|
||||
EnDecrypt.AES encrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt);
|
||||
String textAlgorithm = textAlgorithmBox.getSelectionModel().getSelectedItem();
|
||||
EnDecrypt.AES encrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt, Integer.parseInt(textAlgorithm.substring(textAlgorithm.indexOf('-') + 1)));
|
||||
try {
|
||||
String encryptedText = encrypt.encrypt(textDecryptedEntry.getText());
|
||||
Platform.runLater(() -> {
|
||||
textEncryptedEntry.setText(encryptedText);
|
||||
});
|
||||
Platform.runLater(() -> textEncryptedEntry.setText(encryptedText));
|
||||
} catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException | BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException | IllegalBlockSizeException e) {
|
||||
@ -270,6 +278,8 @@ public class Controller implements Initializable {
|
||||
/**
|
||||
* <p>Decrypt text in {@link Controller#textEncryptedEntry}.
|
||||
* Get called if the text 'Decrypt' button is pressed</p>
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public void textDecryptButton() {
|
||||
final byte[] salt;
|
||||
@ -293,12 +303,11 @@ public class Controller implements Initializable {
|
||||
}
|
||||
}
|
||||
totalThreads.getAndIncrement();
|
||||
EnDecrypt.AES decrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt);
|
||||
String textAlgorithm = textAlgorithmBox.getSelectionModel().getSelectedItem();
|
||||
EnDecrypt.AES decrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt, Integer.parseInt(textAlgorithm.substring(textAlgorithm.indexOf('-') + 1)));
|
||||
try {
|
||||
String DecryptedText = decrypt.decrypt(textEncryptedEntry.getText());
|
||||
Platform.runLater(() -> {
|
||||
textDecryptedEntry.setText(DecryptedText);
|
||||
});
|
||||
Platform.runLater(() -> textDecryptedEntry.setText(DecryptedText));
|
||||
} catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (BadPaddingException e) {
|
||||
@ -335,6 +344,8 @@ public class Controller implements Initializable {
|
||||
* <p>Synchronized method to get the number of threads which en- / decrypt files</p>
|
||||
*
|
||||
* @return number of en- / decryption threads
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private synchronized int getFileEnDecryptThreadsSize() {
|
||||
return fileEnDecryptThreads.size();
|
||||
@ -344,6 +355,8 @@ 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>
|
||||
*
|
||||
* @param thread that should be added
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private synchronized void addFileEnDecryptThread(Thread thread) {
|
||||
fileEnDecryptThreads.add(thread);
|
||||
@ -353,6 +366,8 @@ 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>
|
||||
*
|
||||
* @param thread that should be removed
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private synchronized void removeFileEnDecryptThread(Thread thread) {
|
||||
fileEnDecryptThreads.remove(thread);
|
||||
@ -362,6 +377,8 @@ public class Controller implements Initializable {
|
||||
* <p>Adds a file for en- / decryption</p>
|
||||
*
|
||||
* @param file that should be added
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private void fileEnDecryptAddFile(File file) {
|
||||
for (Label l: enDecryptInputOutputFiles.keySet()) {
|
||||
@ -384,45 +401,29 @@ public class Controller implements Initializable {
|
||||
|
||||
File encryptFile;
|
||||
File decryptFile;
|
||||
String fileOutputPath = file.getParent() + "/";;
|
||||
String fileEnding;
|
||||
ArrayList<File> inputOutputList = new ArrayList<>();
|
||||
if (currentConfigSettings.get("fileOutputPath").trim().isEmpty()) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
decryptFile = new File(fileAbsolutePath + ".cryptoGX");
|
||||
while (decryptFile.isFile()) {
|
||||
decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
encryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + fileName + ".cryptoGX");
|
||||
while (encryptFile.isFile()) {
|
||||
encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX");
|
||||
}
|
||||
if (fileAbsolutePath.endsWith(".cryptoGX")) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
if (!currentConfigSettings.get("fileOutputPath").trim().isEmpty()) {
|
||||
fileOutputPath = currentConfigSettings.get("fileOutputPath").trim() + "/";
|
||||
}
|
||||
if (file.isFile()) {
|
||||
fileEnding = ".cryptoGX";
|
||||
} else {
|
||||
fileEnding = "_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 {
|
||||
decryptFile = new File(fileOutputPath + fileName + fileEnding);
|
||||
}
|
||||
while (decryptFile.exists()) {
|
||||
decryptFile = new File(decryptFile.getAbsolutePath() + fileEnding);
|
||||
}
|
||||
System.out.println(encryptFile.getAbsolutePath() + ";" + decryptFile.getAbsolutePath());
|
||||
inputOutputList.add(0, encryptFile);
|
||||
inputOutputList.add(1, decryptFile);
|
||||
fileEnDecryptInputFiles.getChildren().add(newLabel);
|
||||
@ -435,18 +436,24 @@ public class Controller implements Initializable {
|
||||
* @param url of the file
|
||||
* @param fileType of the file
|
||||
* @throws URISyntaxException
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
private void fileEnDecryptAddInternetFile(String url, int fileType) throws URISyntaxException {
|
||||
String filename;
|
||||
if (fileType == FILEFILEURL) {
|
||||
filename = url.substring(url.lastIndexOf("/") + 1);
|
||||
} else if (fileType == DATAFILEURL) {
|
||||
filename = url.substring(5, url.indexOf("/")) + "." + url.substring(url.indexOf("/") + 1, url.indexOf(";"));
|
||||
} else if (fileType == NONSPECIFICFILEURL) {
|
||||
filename = "unknown" + System.nanoTime();
|
||||
} else {
|
||||
warningAlert("Cannot read given url '" + url + "'");
|
||||
return;
|
||||
switch (fileType) {
|
||||
case FILEFILEURL:
|
||||
filename = url.substring(url.lastIndexOf("/") + 1);
|
||||
break;
|
||||
case DATAFILEURL:
|
||||
filename = url.substring(5, url.indexOf("/")) + "." + url.substring(url.indexOf("/") + 1, url.indexOf(";"));
|
||||
break;
|
||||
case NONSPECIFICFILEURL:
|
||||
filename = "unknown" + System.nanoTime();
|
||||
break;
|
||||
default:
|
||||
warningAlert("Cannot read given url '" + url + "'");
|
||||
return;
|
||||
}
|
||||
for (Label l: enDecryptInputOutputInternetFiles.keySet()) {
|
||||
if (l.getText().equals(filename)) {
|
||||
@ -510,6 +517,8 @@ public class Controller implements Initializable {
|
||||
*
|
||||
* @param image that should be added
|
||||
* @throws URISyntaxException
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
private void fileEnDecryptAddClipboardImage(BufferedImage image) throws URISyntaxException {
|
||||
String filename = "clipboardImage" + System.nanoTime() + ".png";
|
||||
@ -561,6 +570,8 @@ public class Controller implements Initializable {
|
||||
* @param label
|
||||
* @param encryptOutputFile is the filename of the file it gets encrypted
|
||||
* @param decryptOutputFile is the filename of the file it gets decrypted
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private void fileOutputFilesChangeText(Label label, String encryptOutputFile, String decryptOutputFile) {
|
||||
File encryptFile;
|
||||
@ -591,21 +602,13 @@ public class Controller implements Initializable {
|
||||
enDecryptInputOutputFiles.replace(label, change);
|
||||
}
|
||||
|
||||
/**
|
||||
* <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>
|
||||
*
|
||||
* @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>
|
||||
*
|
||||
* @param label that should be deleted
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private void fileEnDecryptDeleteEntry(Label label) {
|
||||
enDecryptInputOutputFiles.remove(label);
|
||||
@ -652,6 +655,8 @@ public class Controller implements Initializable {
|
||||
* 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
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private void fileEnDecryptSelected(Label changeLabel) {
|
||||
if (changeLabel != null) {
|
||||
@ -676,14 +681,16 @@ public class Controller implements Initializable {
|
||||
/**
|
||||
* <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>
|
||||
*
|
||||
* @since 1.12.0
|
||||
*/
|
||||
public void fileEnDecryptChoose() {
|
||||
public void fileEnDecryptChooseFiles() {
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("Choose files");
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*"));
|
||||
List<File> files = fileChooser.showOpenMultipleDialog(rootWindow.getScene().getWindow());
|
||||
try {
|
||||
if (files.size() >= 1) {
|
||||
if (files.size() > 0) {
|
||||
files.forEach(this::fileEnDecryptAddFile);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
@ -691,20 +698,35 @@ 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>
|
||||
*
|
||||
* @param event source
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public void onFileEnDecryptDragOver(DragEvent event) {
|
||||
Dragboard dragboard = event.getDragboard();
|
||||
if (event.getGestureSource() != fileEnDecryptInputFiles) {
|
||||
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()) {
|
||||
String url = dragboard.getUrl();
|
||||
String urlFilename = dragboard.getUrl().split("/")[dragboard.getUrl().split("/").length - 1];
|
||||
@ -717,7 +739,7 @@ public class Controller implements Initializable {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (urlFilename.contains(".") && !Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) {
|
||||
} else if (urlFilename.contains(".") && Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) {
|
||||
try {
|
||||
new URL(url);
|
||||
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
|
||||
@ -737,21 +759,19 @@ public class Controller implements Initializable {
|
||||
*
|
||||
* @param event source
|
||||
* @throws URISyntaxException
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public void onFileEnDecryptDragNDrop(DragEvent event) throws URISyntaxException {
|
||||
Dragboard dragboard = event.getDragboard();
|
||||
if (dragboard.hasFiles()) {
|
||||
dragboard.getFiles().forEach(file -> {
|
||||
if (file.isFile()) {
|
||||
fileEnDecryptAddFile(file);
|
||||
}
|
||||
});
|
||||
dragboard.getFiles().forEach(this::fileEnDecryptAddFile);
|
||||
} else if (dragboard.hasUrl()) {
|
||||
String url = dragboard.getUrl();
|
||||
String urlFilename = dragboard.getUrl().split("/")[dragboard.getUrl().split("/").length - 1];
|
||||
if (url.startsWith("data:")) {
|
||||
fileEnDecryptAddInternetFile(url, DATAFILEURL);
|
||||
} else if (urlFilename.contains(".") && !Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) {
|
||||
} else if (urlFilename.contains(".") && Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) {
|
||||
fileEnDecryptAddInternetFile(url, FILEFILEURL);
|
||||
} else {
|
||||
fileEnDecryptAddInternetFile(url, NONSPECIFICFILEURL);
|
||||
@ -765,6 +785,8 @@ public class Controller implements Initializable {
|
||||
*
|
||||
* @param event source
|
||||
* @throws URISyntaxException
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public void onFileEnDecryptPaste(KeyEvent event) throws URISyntaxException {
|
||||
if (paste.match(event)) {
|
||||
@ -790,6 +812,8 @@ public class Controller implements Initializable {
|
||||
/**
|
||||
* <p>Encrypt all files given files.
|
||||
* Get called if file 'Encrypt' button is pressed</p>
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public void fileEncryptButton() {
|
||||
final byte[] salt;
|
||||
@ -816,27 +840,24 @@ public class Controller implements Initializable {
|
||||
totalThreads.getAndIncrement();
|
||||
Label inputFileLabel = entry.getKey();
|
||||
ArrayList<File> outputFileList = entry.getValue();
|
||||
EnDecrypt.AES fileEncrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt);
|
||||
String fileEnDecryptAlgorithm = fileEnDecryptAlgorithmBox.getSelectionModel().getSelectedItem();
|
||||
EnDecrypt.AES fileEncrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt, Integer.parseInt(fileEnDecryptAlgorithm.substring(fileEnDecryptAlgorithm.indexOf('-') + 1)));
|
||||
if (enDecryptInputOutputInternetFiles.containsKey(inputFileLabel)) {
|
||||
ArrayList<Object> fileSpecs = enDecryptInputOutputInternetFiles.get(inputFileLabel);
|
||||
int urlType = (int) fileSpecs.get(0);
|
||||
String url = (String) fileSpecs.get(1);
|
||||
try {
|
||||
if (urlType == FILEFILEURL) {
|
||||
if (urlType == FILEFILEURL || 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)));
|
||||
fileEncrypt.encryptFile(openURL.getInputStream(), new FileOutputStream((File) fileSpecs.get(2)), buffer);
|
||||
} else if (urlType == DATAFILEURL) {
|
||||
final int dataStartIndex = url.indexOf(",") + 1;
|
||||
final String data = url.substring(dataStartIndex);
|
||||
byte[] decoded = java.util.Base64.getDecoder().decode(data);
|
||||
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)));
|
||||
fileEncrypt.encryptFile(new ByteArrayInputStream(decoded), new FileOutputStream((File) fileSpecs.get(2)), buffer);
|
||||
}
|
||||
} catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
|
||||
} catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -847,17 +868,25 @@ public class Controller implements Initializable {
|
||||
BufferedImage bufferedImage = enDecryptInputOutputClipboardImages.get(inputFileLabel);
|
||||
try {
|
||||
ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
|
||||
fileEncrypt.encryptFileAllInOne(byteArrayOutputStream.toByteArray(), new FileOutputStream(outputFileList.get(0).getAbsoluteFile()));
|
||||
fileEncrypt.encryptFile(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), new FileOutputStream(outputFileList.get(0).getAbsoluteFile()), buffer);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage()));
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | BadPaddingException | InvalidKeySpecException | IllegalBlockSizeException e) {
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
fileEncrypt.encryptFileLineByLine(inputFileLabel.getText(), outputFileList.get(0).getAbsolutePath());
|
||||
} catch (NoSuchPaddingException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException e) {
|
||||
File inputFile = new File(inputFileLabel.getText());
|
||||
if (inputFile.isFile()) {
|
||||
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();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -891,6 +920,8 @@ public class Controller implements Initializable {
|
||||
/**
|
||||
* <p>Decrypt all files given files.
|
||||
* Get called if file 'Decrypt' button is pressed</p>
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public void fileDecryptButton() {
|
||||
final byte[] salt;
|
||||
@ -917,7 +948,8 @@ public class Controller implements Initializable {
|
||||
totalThreads.getAndIncrement();
|
||||
Label inputFileLabel = entry.getKey();
|
||||
ArrayList<File> outputFileList = entry.getValue();
|
||||
EnDecrypt.AES fileDecrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt);
|
||||
String fileEnDecryptAlgorithm = fileEnDecryptAlgorithmBox.getSelectionModel().getSelectedItem();
|
||||
EnDecrypt.AES fileDecrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt, Integer.parseInt(fileEnDecryptAlgorithm.substring(fileEnDecryptAlgorithm.indexOf('-') + 1)));
|
||||
if (enDecryptInputOutputInternetFiles.containsKey(entry.getKey())) {
|
||||
ArrayList<Object> imageSpecs = enDecryptInputOutputInternetFiles.get(entry.getKey());
|
||||
int urlType = (int) imageSpecs.get(0);
|
||||
@ -926,18 +958,19 @@ public class Controller implements Initializable {
|
||||
if (urlType == FILEFILEURL) {
|
||||
URLConnection openURL = new URL(url).openConnection();
|
||||
openURL.addRequestProperty("User-Agent", "Mozilla/5.0");
|
||||
fileDecrypt.decryptFileLineByLine(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)));
|
||||
fileDecrypt.decryptFile(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)), buffer);
|
||||
fileDecrypt.decryptFile(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)), buffer);
|
||||
} else if (urlType == DATAFILEURL) {
|
||||
final int dataStartIndex = url.indexOf(",") + 1;
|
||||
final String data = url.substring(dataStartIndex);
|
||||
byte[] decoded = java.util.Base64.getDecoder().decode(data);
|
||||
fileDecrypt.decryptFileAllInOne(decoded, new FileOutputStream((File) imageSpecs.get(2)));
|
||||
fileDecrypt.decryptFile(new ByteArrayInputStream(decoded), new FileOutputStream((File) imageSpecs.get(2)), buffer);
|
||||
} else if (urlType == NONSPECIFICFILEURL) {
|
||||
URLConnection openURL = new URL(url).openConnection();
|
||||
openURL.addRequestProperty("User-Agent", "Mozilla/5.0");
|
||||
fileDecrypt.decryptFileLineByLine(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)));
|
||||
fileDecrypt.decryptFile(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)), buffer);
|
||||
}
|
||||
} catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
|
||||
} catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -948,17 +981,25 @@ public class Controller implements Initializable {
|
||||
BufferedImage bufferedImage = enDecryptInputOutputClipboardImages.get(inputFileLabel);
|
||||
try {
|
||||
ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
|
||||
fileDecrypt.decryptFileAllInOne(byteArrayOutputStream.toByteArray(), new FileOutputStream(outputFileList.get(1).getAbsolutePath()));
|
||||
fileDecrypt.decryptFile(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), new FileOutputStream(outputFileList.get(1).getAbsolutePath()), buffer);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage()));
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | BadPaddingException | InvalidKeySpecException | IllegalBlockSizeException e) {
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
fileDecrypt.decryptFileLineByLine(inputFileLabel.getText(), outputFileList.get(1).getAbsolutePath());
|
||||
} catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
|
||||
File inputFile = new File(inputFileLabel.getText());
|
||||
if (inputFile.isFile()) {
|
||||
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();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -995,6 +1036,8 @@ public class Controller implements Initializable {
|
||||
/**
|
||||
* <p>Cancels the file en- / decryption.
|
||||
* Get called if the file en- / decrypt 'Cancel' button is pressed</p>
|
||||
*
|
||||
* @since 1.12.0
|
||||
*/
|
||||
public void fileEnDecryptCancelButton() {
|
||||
for (Iterator<Thread> iterator = getFileEnDecryptThreads().iterator(); iterator.hasNext();) {
|
||||
@ -1017,6 +1060,8 @@ public class Controller implements Initializable {
|
||||
* <p>Synchronized method to get the list of threads which delete files</p>
|
||||
*
|
||||
* @return list of threads which delete files
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private synchronized List<Thread> getFileDeleteThreads() {
|
||||
return fileDeleteThreads;
|
||||
@ -1026,6 +1071,8 @@ public class Controller implements Initializable {
|
||||
* <p>Synchronized method to get the number of threads which delete files</p>
|
||||
*
|
||||
* @return number of threads which delete files
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private synchronized int getFileDeleteThreadsSize() {
|
||||
return fileDeleteThreads.size();
|
||||
@ -1035,6 +1082,8 @@ public class Controller implements Initializable {
|
||||
* <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
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private synchronized void addFileDeleteThread(Thread thread) {
|
||||
fileDeleteThreads.add(thread);
|
||||
@ -1044,6 +1093,8 @@ public class Controller implements Initializable {
|
||||
* <p>Synchronized method to remove a thread from the file delete list of current file delete threads</p>
|
||||
*
|
||||
* @param thread that should be removed
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private synchronized void removeFileDeleteThread(Thread thread) {
|
||||
fileDeleteThreads.remove(thread);
|
||||
@ -1053,6 +1104,8 @@ public class Controller implements Initializable {
|
||||
* <p>Adds a file that should be deleted</p>
|
||||
*
|
||||
* @param file that should be added
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private void fileDeleteAddFile(File file) {
|
||||
for (File f: deleteInputFiles.values()) {
|
||||
@ -1064,12 +1117,8 @@ public class Controller implements Initializable {
|
||||
newLabel.setOnKeyTyped(this::keyTypedTooltip);
|
||||
newLabel.setOnMouseMoved(this::mouseOverEntryTooltip);
|
||||
newLabel.setOnMouseExited(event -> mouseExitEntryTooltip());
|
||||
newLabel.setOnMouseClicked(event -> {
|
||||
fileDeleteSelected(newLabel);
|
||||
if (event.getButton() == MouseButton.SECONDARY) {
|
||||
fileDeleteInputContextMenu.show(newLabel, event.getScreenX(), event.getScreenY());
|
||||
}
|
||||
});
|
||||
newLabel.setOnMouseClicked(event -> fileDeleteSelected(newLabel));
|
||||
newLabel.setContextMenu(fileDeleteInputContextMenu);
|
||||
fileDeleteInputFiles.getChildren().add(newLabel);
|
||||
deleteInputFiles.put(newLabel, file.getAbsoluteFile());
|
||||
}
|
||||
@ -1079,6 +1128,8 @@ public class Controller implements Initializable {
|
||||
* 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
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private void fileDeleteSelected(Label changeLabel) {
|
||||
if (changeLabel != null) {
|
||||
@ -1092,21 +1143,13 @@ public class Controller implements Initializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <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>
|
||||
*
|
||||
* @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>
|
||||
*
|
||||
* @param label that should be deleted
|
||||
*
|
||||
* @since 1.12.0
|
||||
*/
|
||||
private void fileDeleteDeleteEntry(Label label) {
|
||||
deleteInputFiles.remove(choosedLabel);
|
||||
@ -1137,34 +1180,51 @@ public class Controller implements Initializable {
|
||||
/**
|
||||
* <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>
|
||||
*
|
||||
* @since 1.12.0
|
||||
*/
|
||||
public void fileDeleteChoose() {
|
||||
public void fileDeleteChooseFiles() {
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("Choose files");
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All Files", "*.*"));
|
||||
List<File> files = fileChooser.showOpenMultipleDialog(rootWindow.getScene().getWindow());
|
||||
try {
|
||||
if (files.size() >= 1) {
|
||||
files.forEach(file -> fileDeleteAddFile(file));
|
||||
if (files.size() > 0) {
|
||||
files.forEach(this::fileDeleteAddFile);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
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>
|
||||
*
|
||||
* @param event source
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public void onFileDeleteDragOver(DragEvent event) {
|
||||
Dragboard dragboard = event.getDragboard();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1172,12 +1232,14 @@ public class Controller implements Initializable {
|
||||
* <p>Get called if the user drops the dragged file over the delete file box</p>
|
||||
*
|
||||
* @param event source
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public void onFileDeleteDragNDrop(DragEvent event) {
|
||||
Dragboard dragboard = event.getDragboard();
|
||||
if (dragboard.hasFiles()) {
|
||||
dragboard.getFiles().forEach(file -> {
|
||||
if (file.isFile()) {
|
||||
if (file.isFile() || file.isDirectory()) {
|
||||
fileDeleteAddFile(file);
|
||||
}
|
||||
});
|
||||
@ -1187,14 +1249,15 @@ public class Controller implements Initializable {
|
||||
/**
|
||||
* <p>Delete all given files.
|
||||
* Get called if 'Delete' button is pressed</p>
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public void fileDelete() {
|
||||
if (!fileDeleteLoading && !deleteInputFiles.isEmpty()) {
|
||||
fileDeleteLoadingImage.setImage(loadingImage);
|
||||
}
|
||||
Iterator<Map.Entry<Label, File>> deleteIterator = deleteInputFiles.entrySet().iterator();
|
||||
while(deleteIterator.hasNext()) {
|
||||
Map.Entry<Label, File> map = deleteIterator.next();
|
||||
int deleteIterations = Integer.parseInt(fileDeleteIterationsEntry.getText());
|
||||
for (Map.Entry<Label, File> map : deleteInputFiles.entrySet()) {
|
||||
Label label = map.getKey();
|
||||
File file = map.getValue();
|
||||
Thread thread = new Thread(() -> {
|
||||
@ -1209,10 +1272,13 @@ public class Controller implements Initializable {
|
||||
}
|
||||
}
|
||||
totalThreads.getAndIncrement();
|
||||
String deleteFile = file.getAbsolutePath();
|
||||
try {
|
||||
SecureDelete.deleteFileLineByLine(deleteFile, Integer.parseInt(fileDeleteIterationsEntry.getText()));
|
||||
} catch (NoSuchAlgorithmException | IOException e) {
|
||||
if (file.isFile()) {
|
||||
SecureDelete.deleteFile(file, deleteIterations, buffer);
|
||||
} else if (file.isDirectory()) {
|
||||
SecureDelete.deleteDirectory(file.getAbsolutePath(), deleteIterations, buffer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if ((getFileDeleteThreadsSize() - 1) <= 0) {
|
||||
@ -1236,6 +1302,8 @@ public class Controller implements Initializable {
|
||||
/**
|
||||
* <p>Cancels the file en- / decryption.
|
||||
* Get called if the file delete 'Cancel' button is pressed</p>
|
||||
*
|
||||
* @since 1.12.0
|
||||
*/
|
||||
public void fileDeleteCancelButton() {
|
||||
for (Iterator<Thread> iterator = getFileDeleteThreads().iterator(); iterator.hasNext();) {
|
||||
@ -1261,14 +1329,14 @@ public class Controller implements Initializable {
|
||||
* @param resources
|
||||
* The resources used to localize the root object, or <tt>null</tt> if
|
||||
* the root object was not localized.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
|
||||
//-----general-----//
|
||||
|
||||
currentConfigSettings.put("encryptHash", configDefaultEncryptHash);
|
||||
|
||||
currentConfigSettings.put("textKey", configDefaultTextKey);
|
||||
currentConfigSettings.put("textSalt", configDefaultTextSalt);
|
||||
currentConfigSettings.put("textAlgorithm", configDefaultTextAlgorithm);
|
||||
@ -1283,9 +1351,6 @@ public class Controller implements Initializable {
|
||||
currentConfigSettings.put("removeFromFileBox", String.valueOf(configDefaultRemoveFileFromFileBox));
|
||||
currentConfigSettings.put("limitNumberOfThreads", String.valueOf(configDefaultLimitNumberOfThreads));
|
||||
|
||||
textAlgorithms.add("AES");
|
||||
fileEnDecryptAlgorithms.add("AES");
|
||||
|
||||
menubar.setOnMouseDragged(event -> {
|
||||
Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
|
||||
stage.setX(event.getScreenX() + menubarX);
|
||||
@ -1300,9 +1365,9 @@ public class Controller implements Initializable {
|
||||
rootWindow.setOnKeyReleased(event -> {
|
||||
if (event.getCode() == KeyCode.DELETE && choosedLabelType != null) {
|
||||
if (choosedLabelType.equals("ENDECRYPT")) {
|
||||
fileEnDecryptDeleteEntry();
|
||||
fileEnDecryptDeleteEntry(choosedLabel);
|
||||
} else if (choosedLabelType.equals("DELETE")) {
|
||||
fileDeleteDeleteEntry();
|
||||
fileDeleteDeleteEntry(choosedLabel);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1363,7 +1428,6 @@ public class Controller implements Initializable {
|
||||
loadSettings.setOnAction(event -> {
|
||||
try {
|
||||
currentConfigSettings = (HashMap<String, String>) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0];
|
||||
System.out.println(currentConfigSettings);
|
||||
textKeyEntry.setText(currentConfigSettings.get("textKey"));
|
||||
textSaltEntry.setText(currentConfigSettings.get("textSalt"));
|
||||
textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm"));
|
||||
@ -1380,9 +1444,9 @@ public class Controller implements Initializable {
|
||||
e.printStackTrace();
|
||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||
try {
|
||||
SecureDelete.deleteFileLineByLine(config, 5);
|
||||
SecureDelete.deleteFile(config, 5, buffer);
|
||||
isConfig = false;
|
||||
} catch (NoSuchAlgorithmException | IOException e) {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -1402,9 +1466,9 @@ public class Controller implements Initializable {
|
||||
File file = fileChooser.showOpenDialog(rootWindow.getScene().getWindow());
|
||||
if (file != null) {
|
||||
if (isConfig) {
|
||||
readUserSettings(file).forEach((Config::addSetting));
|
||||
writeSettings(config, readSettings(file));
|
||||
} else {
|
||||
writeConfig(readUserSettings(file));
|
||||
writeSettings(config, readSettings(file));
|
||||
isConfig = true;
|
||||
}
|
||||
}
|
||||
@ -1412,24 +1476,31 @@ public class Controller implements Initializable {
|
||||
|
||||
//-----text------//
|
||||
|
||||
textAlgorithmBox.setItems(FXCollections.observableArrayList(textAlgorithms));
|
||||
textAlgorithmBox.setValue(textAlgorithms.get(0));
|
||||
textAlgorithmBox.setItems(FXCollections.observableArrayList(Utils.algorithms.keySet()));
|
||||
textAlgorithmBox.setValue(Utils.algorithms.keySet().toArray(new String[Utils.algorithms.size()])[0]);
|
||||
|
||||
//-----fileEnDecrypt-----//
|
||||
|
||||
fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(fileEnDecryptAlgorithms));
|
||||
fileEnDecryptAlgorithmBox.setValue(fileEnDecryptAlgorithms.get(0));
|
||||
fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(Utils.algorithms.keySet()));
|
||||
fileEnDecryptAlgorithmBox.setValue(Utils.algorithms.keySet().toArray(new String[Utils.algorithms.size()])[0]);
|
||||
|
||||
MenuItem enDecryptRemove = new MenuItem();
|
||||
enDecryptRemove.setText("Remove");
|
||||
enDecryptRemove.setOnAction(removeEvent -> fileEnDecryptDeleteEntry());
|
||||
enDecryptRemove.setOnAction(removeEvent -> fileEnDecryptDeleteEntry(choosedLabel));
|
||||
MenuItem enDecryptChangeDest = new MenuItem();
|
||||
enDecryptChangeDest.setText("Change output file");
|
||||
enDecryptChangeDest.setText("Change output file / directory");
|
||||
enDecryptChangeDest.setOnAction(outputFileChangeEvent -> {
|
||||
FileChooser fileDestChooser = new FileChooser();
|
||||
fileDestChooser.setTitle("Choose or create new file");
|
||||
fileDestChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*"));
|
||||
File file = fileDestChooser.showSaveDialog(rootWindow.getScene().getWindow());
|
||||
File file;
|
||||
if (new File(choosedLabel.getText()).isFile()) {
|
||||
FileChooser destChooser = new FileChooser();
|
||||
destChooser.setTitle("Choose or create new file");
|
||||
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) {
|
||||
for (Map.Entry<Label, ArrayList<File>> entry : enDecryptInputOutputFiles.entrySet()) {
|
||||
if (entry.getKey().getText().equals(choosedLabel.getText())) {
|
||||
@ -1496,19 +1567,15 @@ public class Controller implements Initializable {
|
||||
fileOutputFileChangeDest.setDisable(true);
|
||||
getChoosedLabelOutputFileFolder.setDisable(true);
|
||||
|
||||
fileEncryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
fileOutputFilesChangeText(choosedLabel, newValue, fileDecryptOutputFile.getText());
|
||||
});
|
||||
fileDecryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
fileOutputFilesChangeText(choosedLabel, fileEncryptOutputFile.getText(), newValue);
|
||||
});
|
||||
fileEncryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> fileOutputFilesChangeText(choosedLabel, newValue, fileDecryptOutputFile.getText()));
|
||||
fileDecryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> fileOutputFilesChangeText(choosedLabel, fileEncryptOutputFile.getText(), newValue));
|
||||
|
||||
//-----fileDelete-----//
|
||||
|
||||
MenuItem deleteRemove = new MenuItem();
|
||||
deleteRemove.setText("Remove");
|
||||
deleteRemove.setOnAction(removeEvent -> fileDeleteDeleteEntry());
|
||||
fileDeleteInputContextMenu.getItems().addAll(deleteRemove);
|
||||
deleteRemove.setOnAction(removeEvent -> fileDeleteDeleteEntry(choosedLabel));
|
||||
fileDeleteInputContextMenu.getItems().add(deleteRemove);
|
||||
|
||||
ContextMenu fileDeleteInputFilesMenu = new ContextMenu();
|
||||
MenuItem deletePaste = new MenuItem();
|
||||
@ -1547,33 +1614,32 @@ public class Controller implements Initializable {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (isConfig) {
|
||||
Platform.runLater(() -> {
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
currentConfigSettings = (HashMap<String, String>) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0];
|
||||
textKeyEntry.setText(currentConfigSettings.get("textKey"));
|
||||
textSaltEntry.setText(currentConfigSettings.get("textSalt"));
|
||||
textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm"));
|
||||
|
||||
fileEnDecryptKeyEntry.setText(currentConfigSettings.get("fileEnDecryptKey"));
|
||||
fileEnDecryptSaltEntry.setText(currentConfigSettings.get("fileEnDecryptSalt"));
|
||||
fileEnDecryptAlgorithmBox.setValue(currentConfigSettings.get("fileEnDecryptAlgorithm"));
|
||||
|
||||
fileDeleteIterationsEntry.setText(currentConfigSettings.get("fileDeleteIterations"));
|
||||
|
||||
removeFileFromFileBox.setSelected(Boolean.parseBoolean(currentConfigSettings.get("removeFromFileBox")));
|
||||
limitNumberOfThreads.setSelected(Boolean.parseBoolean(currentConfigSettings.get("limitNumberOfThreads")));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||
try {
|
||||
currentConfigSettings = (HashMap<String, String>) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0];
|
||||
System.out.println(currentConfigSettings);
|
||||
textKeyEntry.setText(currentConfigSettings.get("textKey"));
|
||||
textSaltEntry.setText(currentConfigSettings.get("textSalt"));
|
||||
textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm"));
|
||||
|
||||
fileEnDecryptKeyEntry.setText(currentConfigSettings.get("fileEnDecryptKey"));
|
||||
fileEnDecryptSaltEntry.setText(currentConfigSettings.get("fileEnDecryptSalt"));
|
||||
fileEnDecryptAlgorithmBox.setValue(currentConfigSettings.get("fileEnDecryptAlgorithm"));
|
||||
|
||||
fileDeleteIterationsEntry.setText(currentConfigSettings.get("fileDeleteIterations"));
|
||||
|
||||
removeFileFromFileBox.setSelected(Boolean.parseBoolean(currentConfigSettings.get("removeFromFileBox")));
|
||||
limitNumberOfThreads.setSelected(Boolean.parseBoolean(currentConfigSettings.get("limitNumberOfThreads")));
|
||||
SecureDelete.deleteFile(config, 5, buffer);
|
||||
isConfig = false;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||
try {
|
||||
SecureDelete.deleteFileLineByLine(config, 5);
|
||||
isConfig = false;
|
||||
} catch (NoSuchAlgorithmException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
t.start();
|
302
src/org/bytedream/cryptogx/EnDecrypt.java
Normal file
@ -0,0 +1,302 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,10 +1,13 @@
|
||||
/**
|
||||
/*
|
||||
* @author bytedream
|
||||
* @version 1.12.0
|
||||
*
|
||||
* @author blueShard
|
||||
* @version 1.11.0
|
||||
* Some <code>@since</code> versions may be not correct, because the <code>@since</code> tag got added in
|
||||
* 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
|
||||
|
||||
*/
|
||||
|
||||
package org.blueshard.cryptogx;
|
||||
package org.bytedream.cryptogx;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
@ -29,28 +32,30 @@ import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* <p>Main class<p/>
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class Main extends Application {
|
||||
|
||||
protected static final int NON_PORTABLE = 414729643;
|
||||
protected static final int PORTABLE = 245714766;
|
||||
protected static final int NON_PORTABLE = 1;
|
||||
protected static final int PORTABLE = 0;
|
||||
|
||||
protected static final int TYPE = PORTABLE;
|
||||
protected static final int TYPE = NON_PORTABLE;
|
||||
|
||||
protected final static String configDefaultName = "";
|
||||
protected final static String configDefaultEncryptHash = "";
|
||||
protected final static String configDefaultTextKey = "";
|
||||
protected final static String configDefaultTextSalt = "";
|
||||
protected final static String configDefaultTextAlgorithm = "AES";
|
||||
protected final static String configDefaultTextAlgorithm = "AES-128";
|
||||
protected final static String configDefaultFileEnDecryptKey = "";
|
||||
protected final static String configDefaultFileEnDecryptSalt = "";
|
||||
protected final static String configDefaultFileEnDecryptAlgorithm = "AES";
|
||||
protected final static String configDefaultFileEnDecryptAlgorithm = "AES-128";
|
||||
protected final static int configDefaultFileDeleteIterations = 5;
|
||||
protected final static String configDefaultFileOutputPath = "";
|
||||
protected final static boolean configDefaultRemoveFileFromFileBox = false;
|
||||
protected final static boolean configDefaultLimitNumberOfThreads = true;
|
||||
|
||||
protected static ArrayList<String> textAlgorithms = new ArrayList<>();
|
||||
protected static ArrayList<String> fileEnDecryptAlgorithms = new ArrayList<>();
|
||||
private final static byte[] buffer = new byte[64];
|
||||
|
||||
private static Stage mainStage;
|
||||
private double rootWindowX, rootWindowY;
|
||||
@ -62,6 +67,8 @@ public class Main extends Application {
|
||||
*
|
||||
* @param primaryStage of the GUI
|
||||
* @throws IOException if issues with loading 'mainGUI.fxml'
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
@ -74,7 +81,8 @@ public class Main extends Application {
|
||||
primaryStage.setResizable(false);
|
||||
primaryStage.setTitle("cryptoGX");
|
||||
primaryStage.getIcons().add(new Image(getClass().getResource("resources/cryptoGX.png").toExternalForm()));
|
||||
Scene scene = new Scene(root, 900, 470);
|
||||
Scene scene = new Scene(root);
|
||||
//Scene scene = new Scene(root, 900, 470);
|
||||
|
||||
scene.setOnMouseDragged(event -> {
|
||||
primaryStage.setX(event.getScreenX() + rootWindowX);
|
||||
@ -94,7 +102,7 @@ public class Main extends Application {
|
||||
* Can also be used to en- / decrypt text and files or secure delete files without starting GUI</p>
|
||||
*
|
||||
* @param args from the command line
|
||||
* @return status
|
||||
* @return
|
||||
* @throws BadPaddingException
|
||||
* @throws NoSuchAlgorithmException if wrong algorithm is given (command line)
|
||||
* @throws IllegalBlockSizeException if wrong size for key is given (command line)
|
||||
@ -103,11 +111,24 @@ public class Main extends Application {
|
||||
* @throws InvalidKeySpecException
|
||||
* @throws IOException if files cannot be en- / decrypted or deleted correctly (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 {
|
||||
if (Main.TYPE == Main.NON_PORTABLE) {
|
||||
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
|
||||
if (Main.TYPE == Main.PORTABLE) {
|
||||
String system = System.getProperty("os.name").toLowerCase();
|
||||
if (system.startsWith("windows")) {
|
||||
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 {
|
||||
config = new File("cryptoGX.config");
|
||||
}
|
||||
@ -116,19 +137,6 @@ public class Main extends Application {
|
||||
}
|
||||
isConfig = config.isFile();
|
||||
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);
|
||||
} else {
|
||||
args[0] = args[0].replace("-", "");
|
||||
@ -140,7 +148,7 @@ public class Main extends Application {
|
||||
" File en- / decryption\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" +
|
||||
"File secure delete: <iterations> <path of file to delete>");
|
||||
"File secure delete: <cryptoGX jar file> delete <iterations> <path of file to delete>"); //for <iterations> the argument 'default' can be used, which is 5
|
||||
} else if (args[0].toLowerCase().equals("delete")) {
|
||||
if (args.length > 3) {
|
||||
System.err.println("To many arguments were given, expected 3");
|
||||
@ -148,14 +156,28 @@ public class Main extends Application {
|
||||
System.err.println("To few arguments were given, expected 3");
|
||||
}
|
||||
try {
|
||||
SecureDelete.deleteFileLineByLine(args[2], Integer.parseInt(args[1]));
|
||||
if (args[1].equals("default")) {
|
||||
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) {
|
||||
System.err.println(args[1] + " must be a number\n Error: " + e.getMessage());
|
||||
}
|
||||
} else if (args[0].toLowerCase().equals("aes")) {
|
||||
if (args.length < 4) {
|
||||
if (args.length < 5) {
|
||||
System.err.println("To few arguments were given");
|
||||
System.exit(1);
|
||||
} else if (args.length > 6) {
|
||||
System.err.println("To many arguments were given");
|
||||
System.exit(1);
|
||||
}
|
||||
EnDecrypt.AES aes;
|
||||
if (args[2].isEmpty()) {
|
||||
@ -164,18 +186,44 @@ public class Main extends Application {
|
||||
aes = new EnDecrypt.AES(args[1], args[2].getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
String type = args[3].toLowerCase();
|
||||
if (type.equals("encrypt")) {
|
||||
System.out.println(aes.encrypt(args[4]));
|
||||
} else if (type.equals("decrypt")) {
|
||||
System.out.println(aes.decrypt(args[4]));
|
||||
} else if (type.equals("fileencrypt") || type.equals("encryptfile")) {
|
||||
aes.encryptFileLineByLine(args[4], args[5]);
|
||||
} else if (type.equals("filedecrypt") ||type.equals("decryptfile")) {
|
||||
aes.decryptFileLineByLine(args[4], args[5]);
|
||||
if (args.length == 5) {
|
||||
if (type.equals("encrypt")) {
|
||||
System.out.println(Base64.getEncoder().encodeToString(aes.encrypt(args[4].getBytes(StandardCharsets.UTF_8))));
|
||||
} else if (type.equals("decrypt")) {
|
||||
System.out.println(aes.decrypt(args[4]));
|
||||
} else {
|
||||
System.err.println("Couldn't resolve argument " + args[3] + ", expected 'encrypt' or 'decrypt'");
|
||||
System.exit(1);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,6 +231,8 @@ public class Main extends Application {
|
||||
*
|
||||
* @param thread which called this method
|
||||
* @param throwable of the thread which called the method
|
||||
*
|
||||
* @since 1.3.0
|
||||
*/
|
||||
private static void exceptionAlert(Thread thread, Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
@ -193,7 +243,9 @@ public class Main extends Application {
|
||||
Alert enDecryptError = new Alert(Alert.AlertType.ERROR, "Error: " + throwable, ButtonType.OK);
|
||||
enDecryptError.initStyle(StageStyle.UNDECORATED);
|
||||
enDecryptError.setTitle("Error");
|
||||
enDecryptError.setResizable(true);
|
||||
((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();
|
||||
|
||||
@ -223,7 +275,9 @@ public class Main extends Application {
|
||||
"\nError: " + error, ButtonType.OK);
|
||||
enDecryptError.initStyle(StageStyle.UNDECORATED);
|
||||
enDecryptError.setTitle("Error");
|
||||
enDecryptError.setResizable(true);
|
||||
((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();
|
||||
|
||||
@ -243,6 +297,8 @@ public class Main extends Application {
|
||||
* <p>Shows an warning alert window</p>
|
||||
*
|
||||
* @param message that the alert window will show
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
protected static void warningAlert(String message) {
|
||||
AtomicReference<Double> alertX = new AtomicReference<>(Screen.getPrimary().getBounds().getMaxX() / 2);
|
||||
@ -252,6 +308,7 @@ public class Main extends Application {
|
||||
enDecryptError.initStyle(StageStyle.UNDECORATED);
|
||||
enDecryptError.setTitle("Error");
|
||||
((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();
|
||||
|
90
src/org/bytedream/cryptogx/SecureDelete.java
Normal file
@ -0,0 +1,90 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.blueshard.cryptogx;
|
||||
package org.bytedream.cryptoGX;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
@ -16,10 +16,6 @@ import javafx.stage.*;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
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.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -27,16 +23,18 @@ import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.blueshard.cryptogx.Main.*;
|
||||
import static org.bytedream.cryptogx.Main.*;
|
||||
|
||||
/**
|
||||
* <p>Class for the user configuration / settings</p>
|
||||
*
|
||||
* @since 1.12.0
|
||||
*/
|
||||
public class Config {
|
||||
public class Settings {
|
||||
|
||||
private static double addConfigGUIX, addConfigGUIY;
|
||||
private static double addSettingsGUIX, addSettingsGUIY;
|
||||
|
||||
private static final HashSet<String> protectedConfigNames = new HashSet<>(Arrays.asList("cryptoGX", "config"));
|
||||
private static final HashSet<String> protectedSettingsNames = new HashSet<>(Arrays.asList("cryptoGX", "settings"));
|
||||
|
||||
/**
|
||||
* <p>Shows a GUI where the user can save settings, which can load later</p>
|
||||
@ -44,13 +42,15 @@ public class Config {
|
||||
* @param rootWindow from which this GUI will get called
|
||||
* @param userSetting
|
||||
* @throws IOException
|
||||
*
|
||||
* @since 1.11.0
|
||||
*/
|
||||
public static void addSettingGUI(Window rootWindow, Map<String, String> userSetting) throws IOException {
|
||||
Map<String, String> newSettingItems = new HashMap<>();
|
||||
|
||||
Stage rootStage = new Stage();
|
||||
rootStage.initOwner(rootWindow);
|
||||
Parent addSettingsRoot = FXMLLoader.load(Config.class.getResource("resources/addSettingsGUI.fxml"));
|
||||
Parent addSettingsRoot = FXMLLoader.load(Settings.class.getResource("resources/addSettingsGUI.fxml"));
|
||||
rootStage.initStyle(StageStyle.UNDECORATED);
|
||||
rootStage.initModality(Modality.WINDOW_MODAL);
|
||||
rootStage.setResizable(false);
|
||||
@ -60,12 +60,12 @@ public class Config {
|
||||
rootStage.setScene(scene);
|
||||
|
||||
scene.setOnMouseDragged(event -> {
|
||||
rootStage.setX(event.getScreenX() + addConfigGUIX);
|
||||
rootStage.setY(event.getScreenY() + addConfigGUIY);
|
||||
rootStage.setX(event.getScreenX() + addSettingsGUIX);
|
||||
rootStage.setY(event.getScreenY() + addSettingsGUIY);
|
||||
});
|
||||
scene.setOnMousePressed(event -> {
|
||||
addConfigGUIX = scene.getX() - event.getSceneX();
|
||||
addConfigGUIY = scene.getY() - event.getSceneY();
|
||||
addSettingsGUIX = scene.getX() - event.getSceneX();
|
||||
addSettingsGUIY = scene.getY() - event.getSceneY();
|
||||
});
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
@ -78,12 +78,12 @@ public class Config {
|
||||
Platform.runLater(() -> {
|
||||
MenuBar menuBar = (MenuBar) addSettingsRoot.lookup("#menuBar");
|
||||
menuBar.setOnMouseDragged(event -> {
|
||||
rootStage.setX(event.getScreenX() + addConfigGUIX);
|
||||
rootStage.setY(event.getScreenY() + addConfigGUIY);
|
||||
rootStage.setX(event.getScreenX() + addSettingsGUIX);
|
||||
rootStage.setY(event.getScreenY() + addSettingsGUIY);
|
||||
});
|
||||
menuBar.setOnMousePressed(event -> {
|
||||
addConfigGUIX = menuBar.getLayoutX() - event.getSceneX();
|
||||
addConfigGUIY = menuBar.getLayoutY() - event.getSceneY();
|
||||
addSettingsGUIX = menuBar.getLayoutX() - event.getSceneX();
|
||||
addSettingsGUIY = menuBar.getLayoutY() - event.getSceneY();
|
||||
});
|
||||
|
||||
ImageView closeButton = (ImageView) addSettingsRoot.lookup("#closeButton");
|
||||
@ -96,7 +96,7 @@ public class Config {
|
||||
TextField textSaltEntry = (TextField) addSettingsRoot.lookup("#textSaltEntry");
|
||||
textSaltEntry.setText(userSetting.get("textSalt"));
|
||||
ComboBox textAlgorithmBox = (ComboBox) addSettingsRoot.lookup("#textAlgorithmComboBox");
|
||||
textAlgorithmBox.setItems(FXCollections.observableArrayList(textAlgorithms));
|
||||
textAlgorithmBox.setItems(FXCollections.observableArrayList(Utils.algorithms.keySet()));
|
||||
textAlgorithmBox.setValue(userSetting.get("textAlgorithm"));
|
||||
|
||||
TextField fileEnDecryptKeyEntry = (TextField) addSettingsRoot.lookup("#fileEnDecryptKeyEntry");
|
||||
@ -104,7 +104,7 @@ public class Config {
|
||||
TextField fileEnDecryptSaltEntry = (TextField) addSettingsRoot.lookup("#fileEnDecryptSaltEntry");
|
||||
fileEnDecryptSaltEntry.setText(userSetting.get("fileEnDecryptSalt"));
|
||||
ComboBox fileEnDecryptAlgorithmBox = (ComboBox) addSettingsRoot.lookup("#fileEnDecryptAlgorithmComboBox");
|
||||
fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(fileEnDecryptAlgorithms));
|
||||
fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(Utils.algorithms.keySet()));
|
||||
fileEnDecryptAlgorithmBox.setValue(userSetting.get("fileEnDecryptAlgorithm"));
|
||||
|
||||
TextField fileDeleteIterationEntry = (TextField) addSettingsRoot.lookup("#fileDeleteIterationsEntry");
|
||||
@ -117,35 +117,45 @@ public class Config {
|
||||
|
||||
TextField fileOutputPathEntry = (TextField) addSettingsRoot.lookup("#fileOutputPathEntry");
|
||||
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");
|
||||
removeFromFileBoxCheckBox.setSelected(Boolean.parseBoolean(userSetting.get("removeFromFileBox")));
|
||||
CheckBox limitNumberOfThreadsCheckBox = (CheckBox) addSettingsRoot.lookup("#limitNumberOfThreadsCheckBox");
|
||||
limitNumberOfThreadsCheckBox.setSelected(Boolean.parseBoolean(userSetting.get("limitNumberOfThreads")));
|
||||
|
||||
PasswordField hiddenPasswordEntry = (PasswordField) addSettingsRoot.lookup("#hiddenPasswordEntry");
|
||||
TextField showedPasswordEntry = (TextField) addSettingsRoot.lookup("#showedPasswordEntry");
|
||||
TextField visiblePasswordEntry = (TextField) addSettingsRoot.lookup("#visiblePasswordEntry");
|
||||
CheckBox showPassword = (CheckBox) addSettingsRoot.lookup("#showPassword");
|
||||
|
||||
showPassword.setOnAction(event -> {
|
||||
if (showPassword.isSelected()) {
|
||||
showedPasswordEntry.setText(hiddenPasswordEntry.getText());
|
||||
showedPasswordEntry.setVisible(true);
|
||||
visiblePasswordEntry.setText(hiddenPasswordEntry.getText());
|
||||
visiblePasswordEntry.setVisible(true);
|
||||
hiddenPasswordEntry.setVisible(false);
|
||||
} else {
|
||||
hiddenPasswordEntry.setText(showedPasswordEntry.getText());
|
||||
hiddenPasswordEntry.setText(visiblePasswordEntry.getText());
|
||||
hiddenPasswordEntry.setVisible(true);
|
||||
showedPasswordEntry.setVisible(false);
|
||||
visiblePasswordEntry.setVisible(false);
|
||||
}
|
||||
});
|
||||
CheckBox encryptSettings = (CheckBox) addSettingsRoot.lookup("#encryptSettings");
|
||||
encryptSettings.setOnAction(event -> {
|
||||
if (encryptSettings.isSelected()) {
|
||||
hiddenPasswordEntry.setDisable(false);
|
||||
showedPasswordEntry.setDisable(false);
|
||||
visiblePasswordEntry.setDisable(false);
|
||||
showPassword.setDisable(false);
|
||||
} else {
|
||||
hiddenPasswordEntry.setDisable(true);
|
||||
showedPasswordEntry.setDisable(true);
|
||||
visiblePasswordEntry.setDisable(true);
|
||||
showPassword.setDisable(true);
|
||||
}
|
||||
});
|
||||
@ -153,19 +163,23 @@ public class Config {
|
||||
saveButton.setOnAction(event -> {
|
||||
if (settingsNameEntry.getText().trim().isEmpty()) {
|
||||
warningAlert("Add a name for the setting");
|
||||
} else if (protectedConfigNames.contains(settingsNameEntry.getText())) {
|
||||
} else if (protectedSettingsNames.contains(settingsNameEntry.getText())) {
|
||||
warningAlert("Please choose another name for this setting");
|
||||
} else if (encryptSettings.isSelected()){
|
||||
} else if (settingsNameEntry.getText().trim().contains(" ")) {
|
||||
warningAlert("Setting name must not contain free space");
|
||||
} else if (encryptSettings.isSelected()) {
|
||||
try {
|
||||
EnDecrypt.AES encrypt;
|
||||
if (!hiddenPasswordEntry.isDisabled()) {
|
||||
if (!hiddenPasswordEntry.isDisabled() && !hiddenPasswordEntry.getText().trim().isEmpty()) {
|
||||
encrypt = new EnDecrypt.AES(hiddenPasswordEntry.getText(), new byte[16]);
|
||||
newSettingItems.put("encryptHash", encrypt.encrypt(hiddenPasswordEntry.getText()));
|
||||
} else if (!visiblePasswordEntry.getText().trim().isEmpty()) {
|
||||
encrypt = new EnDecrypt.AES(visiblePasswordEntry.getText(), new byte[16]);
|
||||
} else {
|
||||
encrypt = new EnDecrypt.AES(showedPasswordEntry.getText(), new byte[16]);
|
||||
newSettingItems.put("encryptHash", encrypt.encrypt(showedPasswordEntry.getText()));
|
||||
throw new InvalidKeyException("The key must not be empty");
|
||||
}
|
||||
|
||||
newSettingItems.put("encrypted", "true");
|
||||
|
||||
newSettingItems.put("textKey", encrypt.encrypt(textKeyEntry.getText()));
|
||||
newSettingItems.put("textSalt", encrypt.encrypt(textSaltEntry.getText()));
|
||||
newSettingItems.put("textAlgorithm", encrypt.encrypt(textAlgorithmBox.getSelectionModel().getSelectedItem().toString()));
|
||||
@ -180,15 +194,28 @@ public class Config {
|
||||
newSettingItems.put("removeFromFileBox", encrypt.encrypt(String.valueOf(removeFromFileBoxCheckBox.isSelected())));
|
||||
newSettingItems.put("limitNumberOfThreads", encrypt.encrypt(String.valueOf(limitNumberOfThreadsCheckBox.isSelected())));
|
||||
|
||||
addSetting(settingsNameEntry.getText(), newSettingItems);
|
||||
if (!config.isFile()) {
|
||||
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();
|
||||
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException e) {
|
||||
} catch (InvalidKeyException e) {
|
||||
warningAlert("The key must not be empty");
|
||||
} catch (NoSuchPaddingException | NoSuchAlgorithmException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
newSettingItems.put("encryptHash", "");
|
||||
|
||||
newSettingItems.put("textKey", textKeyEntry.getText());
|
||||
newSettingItems.put("textSalt", textSaltEntry.getText());
|
||||
newSettingItems.put("textAlgorithm", textAlgorithmBox.getSelectionModel().getSelectedItem().toString());
|
||||
@ -203,7 +230,20 @@ public class Config {
|
||||
newSettingItems.put("removeFromFileBox", String.valueOf(removeFromFileBoxCheckBox.isSelected()));
|
||||
newSettingItems.put("limitNumberOfThreads", String.valueOf(limitNumberOfThreadsCheckBox.isSelected()));
|
||||
|
||||
addSetting(settingsNameEntry.getText(), newSettingItems);
|
||||
if (!config.isFile()) {
|
||||
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();
|
||||
}
|
||||
@ -221,11 +261,13 @@ public class Config {
|
||||
*
|
||||
* @param rootWindow from which this GUI will get called
|
||||
* @throws IOException
|
||||
*
|
||||
* @since 1.11.0
|
||||
*/
|
||||
public static void exportSettingsGUI(Window rootWindow) throws IOException {
|
||||
Stage rootStage = new Stage();
|
||||
rootStage.initOwner(rootWindow);
|
||||
Parent exportSettingsRoot = FXMLLoader.load(Config.class.getResource("resources/exportSettingsGUI.fxml"));
|
||||
Parent exportSettingsRoot = FXMLLoader.load(Settings.class.getResource("resources/exportSettingsGUI.fxml"));
|
||||
rootStage.initStyle(StageStyle.UNDECORATED);
|
||||
rootStage.initModality(Modality.WINDOW_MODAL);
|
||||
rootStage.setResizable(false);
|
||||
@ -235,12 +277,12 @@ public class Config {
|
||||
rootStage.setScene(scene);
|
||||
|
||||
scene.setOnMouseDragged(event -> {
|
||||
rootStage.setX(event.getScreenX() + addConfigGUIX);
|
||||
rootStage.setY(event.getScreenY() + addConfigGUIY);
|
||||
rootStage.setX(event.getScreenX() + addSettingsGUIX);
|
||||
rootStage.setY(event.getScreenY() + addSettingsGUIY);
|
||||
});
|
||||
scene.setOnMousePressed(event -> {
|
||||
addConfigGUIX = scene.getX() - event.getSceneX();
|
||||
addConfigGUIY = scene.getY() - event.getSceneY();
|
||||
addSettingsGUIX = scene.getX() - event.getSceneX();
|
||||
addSettingsGUIY = scene.getY() - event.getSceneY();
|
||||
});
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
@ -251,18 +293,18 @@ public class Config {
|
||||
}
|
||||
MenuBar menuBar = (MenuBar) exportSettingsRoot.lookup("#menuBar");
|
||||
menuBar.setOnMouseDragged(event -> {
|
||||
rootStage.setX(event.getScreenX() + addConfigGUIX);
|
||||
rootStage.setY(event.getScreenY() + addConfigGUIY);
|
||||
rootStage.setX(event.getScreenX() + addSettingsGUIX);
|
||||
rootStage.setY(event.getScreenY() + addSettingsGUIY);
|
||||
});
|
||||
menuBar.setOnMousePressed(event -> {
|
||||
addConfigGUIX = menuBar.getLayoutX() - event.getSceneX();
|
||||
addConfigGUIY = menuBar.getLayoutY() - event.getSceneY();
|
||||
addSettingsGUIX = menuBar.getLayoutX() - event.getSceneX();
|
||||
addSettingsGUIY = menuBar.getLayoutY() - event.getSceneY();
|
||||
});
|
||||
ImageView closeButton = (ImageView) exportSettingsRoot.lookup("#closeButton");
|
||||
closeButton.setOnMouseClicked(event -> rootStage.close());
|
||||
|
||||
VBox settingsBox = (VBox) exportSettingsRoot.lookup("#settingsBox");
|
||||
Platform.runLater(() -> readUserSettings().keySet().forEach(s -> {
|
||||
Platform.runLater(() -> readSettings(config).keySet().forEach(s -> {
|
||||
CheckBox newCheckBox = new CheckBox();
|
||||
newCheckBox.setText(s);
|
||||
settingsBox.getChildren().add(newCheckBox);
|
||||
@ -273,12 +315,12 @@ public class Config {
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("Export settings");
|
||||
fileChooser.setInitialFileName("settings.config");
|
||||
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Config files", "*.config", "*.xml"),
|
||||
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Config files", "*.config"),
|
||||
new FileChooser.ExtensionFilter("All files", "*.*"));
|
||||
File file = fileChooser.showSaveDialog(exportSettingsRoot.getScene().getWindow());
|
||||
if (file != null) {
|
||||
TreeMap<String, Map<String, String>> writeInfos = new TreeMap<>();
|
||||
TreeMap<String, Map<String, String>> settings = readUserSettings();
|
||||
TreeMap<String, Map<String, String>> settings = readSettings(config);
|
||||
for (int i=0; i<settingsBox.getChildren().size(); i++) {
|
||||
CheckBox checkBox = (CheckBox) settingsBox.getChildren().get(i);
|
||||
if (checkBox.isSelected()) {
|
||||
@ -289,7 +331,7 @@ public class Config {
|
||||
if (!file.getAbsolutePath().contains(".")) {
|
||||
file = new File(file.getAbsolutePath() + ".config");
|
||||
}
|
||||
writeConfig(file, writeInfos);
|
||||
writeSettings(file, writeInfos);
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -305,30 +347,32 @@ public class Config {
|
||||
* @param rootWindow from which this GUI will get called
|
||||
* @return the settings that the user has chosen
|
||||
* @throws IOException
|
||||
*
|
||||
* @since 1.11.0
|
||||
*/
|
||||
public static TreeMap<String, Map<String, String>> loadSettingsGUI(Window rootWindow) throws IOException {
|
||||
Button[] outerLoadButton = new Button[1];
|
||||
HashMap<String, String> setting = new HashMap<>();
|
||||
TreeMap<String, Map<String, String>> settingItems = readUserSettings();
|
||||
TreeMap<String, Map<String, String>> settingItems = readSettings(config);
|
||||
TreeMap<String, Map<String, String>> returnItems = new TreeMap<>();
|
||||
|
||||
Stage rootStage = new Stage();
|
||||
rootStage.initOwner(rootWindow);
|
||||
AnchorPane loadSettingsRoot = FXMLLoader.load(Config.class.getResource("resources/loadSettingsGUI.fxml"));
|
||||
AnchorPane loadSettingsRoot = FXMLLoader.load(Settings.class.getResource("resources/loadSettingsGUI.fxml"));
|
||||
rootStage.initStyle(StageStyle.UNDECORATED);
|
||||
rootStage.initModality(Modality.WINDOW_MODAL);
|
||||
rootStage.setResizable(false);
|
||||
rootStage.setTitle("cryptoGX");
|
||||
rootStage.getIcons().add(new Image(Config.class.getResource("resources/cryptoGX.png").toExternalForm()));
|
||||
rootStage.getIcons().add(new Image(Settings.class.getResource("resources/cryptoGX.png").toExternalForm()));
|
||||
Scene scene = new Scene(loadSettingsRoot, 242, 235);
|
||||
|
||||
scene.setOnMouseDragged(event -> {
|
||||
rootStage.setX(event.getScreenX() + addConfigGUIX);
|
||||
rootStage.setY(event.getScreenY() + addConfigGUIY);
|
||||
rootStage.setX(event.getScreenX() + addSettingsGUIX);
|
||||
rootStage.setY(event.getScreenY() + addSettingsGUIY);
|
||||
});
|
||||
scene.setOnMousePressed(event -> {
|
||||
addConfigGUIX = scene.getX() - event.getSceneX();
|
||||
addConfigGUIY = scene.getY() - event.getSceneY();
|
||||
addSettingsGUIX = scene.getX() - event.getSceneX();
|
||||
addSettingsGUIY = scene.getY() - event.getSceneY();
|
||||
});
|
||||
|
||||
scene.setOnKeyReleased(event -> {
|
||||
@ -346,12 +390,12 @@ public class Config {
|
||||
Platform.runLater(() -> {
|
||||
MenuBar menuBar = (MenuBar) loadSettingsRoot.lookup("#menuBar");
|
||||
menuBar.setOnMouseDragged(event -> {
|
||||
rootStage.setX(event.getScreenX() + addConfigGUIX);
|
||||
rootStage.setY(event.getScreenY() + addConfigGUIY);
|
||||
rootStage.setX(event.getScreenX() + addSettingsGUIX);
|
||||
rootStage.setY(event.getScreenY() + addSettingsGUIY);
|
||||
});
|
||||
menuBar.setOnMousePressed(event -> {
|
||||
addConfigGUIX = menuBar.getLayoutX() - event.getSceneX();
|
||||
addConfigGUIY = menuBar.getLayoutY() - event.getSceneY();
|
||||
addSettingsGUIX = menuBar.getLayoutX() - event.getSceneX();
|
||||
addSettingsGUIY = menuBar.getLayoutY() - event.getSceneY();
|
||||
});
|
||||
|
||||
ImageView closeButton = (ImageView) loadSettingsRoot.lookup("#closeButton");
|
||||
@ -360,8 +404,6 @@ public class Config {
|
||||
}
|
||||
|
||||
closeButton.setOnMouseClicked(event -> {
|
||||
setting.put("encryptHash", configDefaultEncryptHash);
|
||||
|
||||
setting.put("textKey", configDefaultTextKey);
|
||||
setting.put("textSalt", configDefaultTextSalt);
|
||||
setting.put("textAlgorithm", configDefaultTextAlgorithm);
|
||||
@ -400,7 +442,7 @@ public class Config {
|
||||
ComboBox settingsBox = (ComboBox) loadSettingsRoot.lookup("#settingsBox");
|
||||
settingsBox.setItems(FXCollections.observableArrayList(settingItems.keySet()));
|
||||
settingsBox.setValue(settingItems.firstKey());
|
||||
if (settingItems.firstEntry().getValue().get("encryptHash").trim().isEmpty()) {
|
||||
if (!Boolean.parseBoolean(settingItems.firstEntry().getValue().get("encrypted").trim())) {
|
||||
keyHideEntry.clear();
|
||||
keyHideEntry.setDisable(true);
|
||||
keyShowEntry.setDisable(true);
|
||||
@ -408,7 +450,7 @@ public class Config {
|
||||
}
|
||||
settingsBox.setOnAction(event -> {
|
||||
try {
|
||||
if (settingItems.get(settingsBox.getSelectionModel().getSelectedItem().toString()).get("encryptHash").trim().isEmpty()) {
|
||||
if (!Boolean.parseBoolean(settingItems.get(settingsBox.getSelectionModel().getSelectedItem().toString()).get("encrypted").trim())) {
|
||||
keyHideEntry.clear();
|
||||
keyHideEntry.setDisable(true);
|
||||
keyShowEntry.clear();
|
||||
@ -431,8 +473,6 @@ public class Config {
|
||||
String settingName = settingsBox.getSelectionModel().getSelectedItem().toString();
|
||||
Map<String, String> selectedSetting = settingItems.get(settingName);
|
||||
if (keyHideEntry.isDisabled() && showPassword.isDisabled() && showPassword.isDisabled()) {
|
||||
setting.put("encryptHash", "");
|
||||
|
||||
setting.put("textKey", selectedSetting.get("textKey"));
|
||||
setting.put("textSalt", selectedSetting.get("textSalt"));
|
||||
setting.put("textAlgorithm", selectedSetting.get("textAlgorithm"));
|
||||
@ -458,33 +498,29 @@ public class Config {
|
||||
decryptSetting = new EnDecrypt.AES(keyShowEntry.getText(), new byte[16]);
|
||||
}
|
||||
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);
|
||||
setting.put("textKey", decryptSetting.decrypt(selectedEncryptedSetting.get("textKey")));
|
||||
setting.put("textSalt", decryptSetting.decrypt(selectedEncryptedSetting.get("textSalt")));
|
||||
setting.put("textAlgorithm", decryptSetting.decrypt(selectedEncryptedSetting.get("textAlgorithm")));
|
||||
Map<String, String> selectedEncryptedSetting = settingItems.get(settingName);
|
||||
setting.put("textKey", decryptSetting.decrypt(selectedEncryptedSetting.get("textKey")));
|
||||
setting.put("textSalt", decryptSetting.decrypt(selectedEncryptedSetting.get("textSalt")));
|
||||
setting.put("textAlgorithm", decryptSetting.decrypt(selectedEncryptedSetting.get("textAlgorithm")));
|
||||
|
||||
setting.put("fileEnDecryptKey", decryptSetting.decrypt(selectedEncryptedSetting.get("fileEnDecryptKey")));
|
||||
setting.put("fileEnDecryptSalt", decryptSetting.decrypt(selectedEncryptedSetting.get("fileEnDecryptSalt")));
|
||||
setting.put("fileEnDecryptAlgorithm", decryptSetting.decrypt(selectedEncryptedSetting.get("fileEnDecryptAlgorithm")));
|
||||
setting.put("fileEnDecryptKey", decryptSetting.decrypt(selectedEncryptedSetting.get("fileEnDecryptKey")));
|
||||
setting.put("fileEnDecryptSalt", decryptSetting.decrypt(selectedEncryptedSetting.get("fileEnDecryptSalt")));
|
||||
setting.put("fileEnDecryptAlgorithm", decryptSetting.decrypt(selectedEncryptedSetting.get("fileEnDecryptAlgorithm")));
|
||||
|
||||
setting.put("fileDeleteIterations", String.valueOf(Integer.parseInt(decryptSetting.decrypt(selectedEncryptedSetting.get("fileDeleteIterations")))));
|
||||
setting.put("fileDeleteIterations", String.valueOf(Integer.parseInt(decryptSetting.decrypt(selectedEncryptedSetting.get("fileDeleteIterations")))));
|
||||
|
||||
setting.put("fileOutputPath", decryptSetting.decrypt(selectedEncryptedSetting.get("fileOutputPath")));
|
||||
setting.put("removeFromFileBox", decryptSetting.decrypt(selectedEncryptedSetting.get("removeFromFileBox")));
|
||||
setting.put("limitNumberOfThreads", decryptSetting.decrypt(selectedEncryptedSetting.get("limitNumberOfThreads")));
|
||||
setting.put("fileOutputPath", decryptSetting.decrypt(selectedEncryptedSetting.get("fileOutputPath")));
|
||||
setting.put("removeFromFileBox", decryptSetting.decrypt(selectedEncryptedSetting.get("removeFromFileBox")));
|
||||
setting.put("limitNumberOfThreads", decryptSetting.decrypt(selectedEncryptedSetting.get("limitNumberOfThreads")));
|
||||
|
||||
returnItems.put(settingsBox.getSelectionModel().getSelectedItem().toString(), setting);
|
||||
returnItems.put(settingsBox.getSelectionModel().getSelectedItem().toString(), setting);
|
||||
|
||||
rootStage.close();
|
||||
}
|
||||
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
rootStage.close();
|
||||
} catch (InvalidKeyException e) {
|
||||
warningAlert("Wrong key is given");
|
||||
} catch (NoSuchPaddingException | NoSuchAlgorithmException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
warningAlert("Wrong key is given or the config wasn't\nsaved correctly");
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -497,7 +533,7 @@ public class Config {
|
||||
Alert deleteQuestion = new Alert(Alert.AlertType.CONFIRMATION, "Delete " + settingsBox.getSelectionModel().getSelectedItem().toString() + "?", ButtonType.OK, ButtonType.CANCEL);
|
||||
deleteQuestion.initStyle(StageStyle.UNDECORATED);
|
||||
deleteQuestion.setTitle("Confirmation");
|
||||
((Stage) deleteQuestion.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Config.class.getResource("resources/cryptoGX.png").toExternalForm()));
|
||||
((Stage) deleteQuestion.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Settings.class.getResource("resources/cryptoGX.png").toExternalForm()));
|
||||
|
||||
Scene window = deleteQuestion.getDialogPane().getScene();
|
||||
|
||||
@ -512,24 +548,28 @@ public class Config {
|
||||
|
||||
Optional<ButtonType> result = deleteQuestion.showAndWait();
|
||||
if (result.get() == ButtonType.OK) {
|
||||
deleteUserSetting(settingsBox.getSelectionModel().getSelectedItem().toString());
|
||||
settingItems.clear();
|
||||
settingItems.putAll(readUserSettings());
|
||||
if (settingItems.size() == 0) {
|
||||
for (int i=0; i<100; i++) {
|
||||
if (settingItems.size() - 1 <= 0) {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
if (config.isFile()) {
|
||||
if (config.delete()) {
|
||||
try {
|
||||
SecureDelete.deleteFile(config, 5, new byte[64]);
|
||||
isConfig = false;
|
||||
rootStage.close();
|
||||
break;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
rootStage.close();
|
||||
return;
|
||||
} else if (deleteSetting(config, settingsBox.getSelectionModel().getSelectedItem().toString())) {
|
||||
settingItems.remove(settingsBox.getSelectionModel().getSelectedItem().toString());
|
||||
|
||||
settingsBox.setItems(FXCollections.observableArrayList(settingItems.keySet()));
|
||||
settingsBox.setValue(settingItems.firstKey());
|
||||
} else {
|
||||
warningAlert("Couldn't delete setting '" + settingsBox.getSelectionModel().getSelectedItem().toString() + "'");
|
||||
}
|
||||
settingsBox.setItems(FXCollections.observableArrayList(settingItems.keySet()));
|
||||
settingsBox.setValue(settingItems.firstKey());
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -547,242 +587,152 @@ public class Config {
|
||||
* <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
|
||||
*/
|
||||
public static void addSetting(String settingName, Map<String, String> userSetting) {
|
||||
TreeMap<String, Map<String, String>> newConfig = new TreeMap<>(readUserSettings());
|
||||
newConfig.put(settingName, userSetting);
|
||||
writeConfig(newConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Shows a GUI where the user can save the current settings</p>
|
||||
* @param newSetting is the new setting key value pair
|
||||
*
|
||||
* @param settingName name of the new setting
|
||||
* @param userSetting the current settings
|
||||
* @param encryptPassword to encrypt the settings
|
||||
* @since 1.12.0
|
||||
*/
|
||||
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));
|
||||
public static void addSetting(File file, String settingName, Map<String, String> newSetting) {
|
||||
TreeMap<String, Map<String, String>> settings = readSettings(file);
|
||||
settings.put(settingName, newSetting);
|
||||
writeSettings(file, settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Deletes a saved setting</p>
|
||||
*
|
||||
* @param name of the setting
|
||||
* @param settingName of the setting
|
||||
* @return if the setting could be found
|
||||
*
|
||||
* @since 1.12.0
|
||||
*/
|
||||
public static boolean deleteUserSetting(String name) {
|
||||
TreeMap<String, Map<String, String>> newSetting = new TreeMap<>();
|
||||
TreeMap<String, Map<String, String>> oldSetting = readUserSettings();
|
||||
public static boolean deleteSetting(File file, String settingName) {
|
||||
StringBuilder newConfig = new StringBuilder();
|
||||
boolean delete = false;
|
||||
boolean found = false;
|
||||
|
||||
for (Map.Entry<String, Map<String, String>> entry: oldSetting.entrySet()) {
|
||||
if (!entry.getKey().equals(name)) {
|
||||
newSetting.put(entry.getKey(), entry.getValue());
|
||||
} else {
|
||||
found = true;
|
||||
try {
|
||||
BufferedReader configReader = new BufferedReader(new FileReader(file));
|
||||
|
||||
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 {
|
||||
newConfig.append(line).append("\n");
|
||||
}
|
||||
} else if (!delete) {
|
||||
newConfig.append(line).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
configReader.close();
|
||||
|
||||
BufferedWriter configFile = new BufferedWriter(new FileWriter(file));
|
||||
configFile.write(newConfig.toString());
|
||||
configFile.newLine();
|
||||
|
||||
configFile.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
writeConfig(newSetting);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
public static TreeMap<String, Map<String, String>> readUserSettings() {
|
||||
return readUserSettings(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Config#readUserSettings(String)
|
||||
* <p>Reads all settings saved in a file</>
|
||||
*
|
||||
* @param file from which the settings should be read from
|
||||
* @return the settings
|
||||
*
|
||||
* @since 1.12.0
|
||||
*/
|
||||
public static TreeMap<String, Map<String, String>> readUserSettings(File file) {
|
||||
TreeMap<String, Map<String, String>> rootInfos = new TreeMap<>();
|
||||
public static TreeMap<String, Map<String, String>> readSettings(File file) {
|
||||
TreeMap<String, Map<String, String>> returnMap = new TreeMap<>();
|
||||
String settingName = null;
|
||||
Map<String, String> settingValues = new HashMap<>();
|
||||
|
||||
try {
|
||||
XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
|
||||
XMLStreamReader xmlStreamReader;
|
||||
try {
|
||||
xmlStreamReader = xmlInputFactory.createXMLStreamReader(new FileInputStream(file));
|
||||
} catch (FileNotFoundException e) {
|
||||
return rootInfos;
|
||||
}
|
||||
BufferedReader configReader = new BufferedReader(new FileReader(file));
|
||||
|
||||
HashMap<String, String> infos = new HashMap<>();
|
||||
String line;
|
||||
|
||||
String infoName = null;
|
||||
StringBuilder infoCharacters = new StringBuilder();
|
||||
String rootName = null;
|
||||
while ((line = configReader.readLine()) != 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;
|
||||
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 {
|
||||
settingValues.put(keyValue[0], keyValue[1]);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
settingValues.put(keyValue[0], "");
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlStreamReader.close();
|
||||
} catch (XMLStreamException e) {
|
||||
|
||||
if (settingName != null) {
|
||||
returnMap.put(settingName, settingValues);
|
||||
}
|
||||
|
||||
configReader.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
warningAlert("Couldn't find file '" + file.getAbsolutePath() + "'"); // this should never raise
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
errorAlert("An IO Exception occurred", e.getMessage());
|
||||
}
|
||||
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);
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Writes settings (could be more than one) to a file</p>
|
||||
*
|
||||
* @param file where the settings should be written in
|
||||
* @param userSettings of the user
|
||||
* @param encryptedSettings says which settings from {@param userSettings} should be encrypted with a password
|
||||
* @param settings of the user
|
||||
*
|
||||
* @since 1.12.0
|
||||
*/
|
||||
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<>();
|
||||
}
|
||||
|
||||
public static void writeSettings(File file, TreeMap<String, Map<String, String>> settings) {
|
||||
try {
|
||||
XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
|
||||
XMLStreamWriter xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(stringWriter);
|
||||
BufferedWriter configWriter = new BufferedWriter(new FileWriter(file));
|
||||
|
||||
xmlStreamWriter.writeStartDocument();
|
||||
xmlStreamWriter.writeStartElement("cryptoGX");
|
||||
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()) {
|
||||
xmlStreamWriter.writeStartElement(entry.getKey());
|
||||
xmlStreamWriter.writeCharacters(encryptSetting.encrypt(entry.getValue()));
|
||||
xmlStreamWriter.writeEndElement();
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<String, String> entry: settingElement.getValue().entrySet()) {
|
||||
xmlStreamWriter.writeStartElement(entry.getKey());
|
||||
xmlStreamWriter.writeCharacters(entry.getValue());
|
||||
xmlStreamWriter.writeEndElement();
|
||||
for (Map.Entry<String, Map<String, String>> settingElement: settings.entrySet()) {
|
||||
configWriter.write("[" + settingElement.getKey() + " encrypted=" + Boolean.parseBoolean(settingElement.getValue().get("encrypted")) + "]");
|
||||
configWriter.newLine();
|
||||
for (Map.Entry<String, String> entry : settingElement.getValue().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (!key.equals("encrypted")) {
|
||||
configWriter.write(entry.getKey() + "=" + entry.getValue());
|
||||
configWriter.newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlStreamWriter.writeEndElement();
|
||||
}
|
||||
xmlStreamWriter.writeEndElement();
|
||||
xmlStreamWriter.writeEndDocument();
|
||||
configWriter.newLine();
|
||||
|
||||
//prettify
|
||||
|
||||
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) {
|
||||
configWriter.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
errorAlert("An error occurred while saving the settings", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
51
src/org/bytedream/cryptogx/Utils.java
Normal file
@ -0,0 +1,51 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Accordion?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?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?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.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">
|
||||
<children>
|
||||
@ -22,8 +13,8 @@
|
||||
<Image url="@close.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
<Text fx:id="saveSettingsText" layoutX="125.0" layoutY="46.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Save settings" />
|
||||
<Text fx:id="nameOfSettingText" layoutX="77.0" layoutY="86.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Name of the new configuration" />
|
||||
<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="nameOfSettingText" layoutX="49.0" layoutY="90.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Name of the new configuration" textAlignment="CENTER" wrappingWidth="221.84912109375" />
|
||||
<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">
|
||||
<panes>
|
||||
@ -69,11 +60,11 @@
|
||||
<content>
|
||||
<AnchorPane fx:id="settingsPane" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
|
||||
<children>
|
||||
<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="41.0" prefHeight="25.0" prefWidth="280.0" />
|
||||
<Button fx:id="fileOutputPathButton" layoutX="85.0" layoutY="78.0" mnemonicParsing="false" text="Change output path" />
|
||||
<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="151.0" mnemonicParsing="false" text="Limit number of threads" />
|
||||
<Text fx:id="fileOutputPathText" layoutX="10.0" layoutY="20.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" />
|
||||
<Button fx:id="fileOutputPathButton" layoutX="71.0" layoutY="66.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="157.0" text="Change output path" textAlignment="CENTER" />
|
||||
<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="limitNumberOfThreadsCheckBox" layoutX="10.0" layoutY="149.0" mnemonicParsing="false" text="Limit number of threads" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</content>
|
||||
@ -83,7 +74,7 @@
|
||||
<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" />
|
||||
<PasswordField fx:id="hiddenPasswordEntry" disable="true" layoutX="10.0" layoutY="490.0" prefHeight="25.0" prefWidth="300.0" promptText="Password" />
|
||||
<TextField fx:id="showedPasswordEntry" disable="true" layoutX="10.0" layoutY="490.0" prefHeight="25.0" prefWidth="300.0" promptText="Password" visible="false" />
|
||||
<TextField fx:id="visiblePasswordEntry" 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" />
|
||||
<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" />
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
@ -1,13 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.MenuBar?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?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?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.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">
|
||||
<children>
|
||||
@ -17,12 +13,12 @@
|
||||
<Image url="@close.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
<Text fx:id="exportSettingsText" layoutX="88.0" layoutY="48.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Export settings" />
|
||||
<Text fx:id="exportSettingsText" layoutX="68.0" layoutY="49.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Export settings" textAlignment="CENTER" wrappingWidth="117.5283203125" />
|
||||
<ScrollPane layoutX="7.0" layoutY="64.0" prefHeight="120.0" prefWidth="240.0">
|
||||
<content>
|
||||
<VBox fx:id="settingsBox" prefHeight="118.0" prefWidth="238.0" />
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<Button fx:id="exportButton" layoutX="98.0" layoutY="203.0" mnemonicParsing="false" text="Export..." />
|
||||
<Button fx:id="exportButton" layoutX="86.0" layoutY="203.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="82.0" text="Export..." textAlignment="CENTER" />
|
||||
</children>
|
||||
</AnchorPane>
|
@ -13,11 +13,10 @@
|
||||
<Image url="@close.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
<Text fx:id="loadSettingsText" layoutX="86.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Load settings" />
|
||||
<Text fx:id="loadSettingsText" layoutX="68.0" layoutY="47.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Load settings" textAlignment="CENTER" wrappingWidth="107.38818359375" />
|
||||
<ComboBox fx:id="settingsBox" layoutX="24.0" layoutY="72.0" prefHeight="25.0" prefWidth="194.0" />
|
||||
<Text fx:id="passwordText" layoutX="14.0" layoutY="136.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Password" />
|
||||
<PasswordField fx:id="passwordEntryHide" layoutX="79.0" layoutY="119.0" />
|
||||
<TextField fx:id="passwordEntryShow" layoutX="79.0" layoutY="119.0" visible="false" />
|
||||
<PasswordField fx:id="passwordEntryHide" layoutX="16.0" layoutY="118.0" prefHeight="26.0" prefWidth="211.0" promptText="Password" />
|
||||
<TextField fx:id="passwordEntryShow" layoutX="16.0" layoutY="118.0" prefHeight="26.0" prefWidth="211.0" visible="false" />
|
||||
<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" />
|
||||
<Button fx:id="loadButton" layoutX="29.0" layoutY="193.0" mnemonicParsing="false" text="Load" />
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
@ -1,23 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ComboBox?>
|
||||
<?import javafx.scene.control.Menu?>
|
||||
<?import javafx.scene.control.MenuBar?>
|
||||
<?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?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.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.blueshard.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.bytedream.cryptogx.Controller">
|
||||
<children>
|
||||
<MenuBar fx:id="menubar" prefHeight="25.0" prefWidth="900.0">
|
||||
<menus>
|
||||
@ -29,7 +18,7 @@
|
||||
<Menu fx:id="settingsMenu" mnemonicParsing="false" text="Settings">
|
||||
<items>
|
||||
<MenuItem fx:id="setDefaultOutputPath" mnemonicParsing="false" text="Set default file en- / decryption output path..." />
|
||||
<RadioMenuItem fx:id="removeFileFromFileBox" mnemonicParsing="false" text="Remove files from filebox after en- / decryption" />
|
||||
<RadioMenuItem fx:id="removeFileFromFileBox" mnemonicParsing="false" text="Remove files from file box after en- / decryption" />
|
||||
<RadioMenuItem fx:id="limitNumberOfThreads" mnemonicParsing="false" selected="true" text="Limit number of threads" />
|
||||
<SeparatorMenuItem fx:id="settingsSeparator1" mnemonicParsing="false" />
|
||||
<MenuItem fx:id="saveSettings" mnemonicParsing="false" text="Save settings..." />
|
||||
@ -37,7 +26,7 @@
|
||||
<MenuItem fx:id="exportSettings" disable="true" mnemonicParsing="false" text="Export settings..." />
|
||||
<MenuItem fx:id="importSettings" mnemonicParsing="false" text="Import settings..." />
|
||||
</items></Menu>
|
||||
<Menu fx:id="helpMenu" mnemonicParsing="false" text="Help" />
|
||||
<Menu fx:id="helpMenu" mnemonicParsing="false" text="Help"/>
|
||||
</menus>
|
||||
</MenuBar>
|
||||
<ImageView fx:id="minimizeWindow" fitHeight="25.0" fitWidth="25.0" layoutX="850.0" onMouseClicked="#minimizeApplication" pickOnBounds="true" preserveRatio="true">
|
||||
@ -48,56 +37,62 @@
|
||||
<image>
|
||||
<Image url="@close.png" />
|
||||
</image></ImageView>
|
||||
<Text fx:id="textText" layoutX="103.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="En- / decrypt Text" />
|
||||
<TextField fx:id="textKeyEntry" layoutX="76.0" layoutY="64.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" promptText="Key" />
|
||||
<Text fx:id="textText" layoutX="81.0" layoutY="49.0" strokeType="OUTSIDE" strokeWidth="0.0" text="En- / decrypt Text" textAlignment="CENTER" wrappingWidth="135.9" />
|
||||
<TextField fx:id="textKeyEntry" layoutX="74.0" layoutY="64.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="155.0" 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="textEncryptedEntry" layoutX="7.0" layoutY="222.0" onKeyTyped="#keyTypedTooltip" prefHeight="105.0" prefWidth="286.0" promptText="Encrypted Text" />
|
||||
<Button fx:id="textEncryptButton" layoutX="47.0" layoutY="339.0" mnemonicParsing="false" onAction="#textEncryptButton" text="Encrypt" />
|
||||
<Button fx:id="textEncryptButton" layoutX="29.0" layoutY="339.0" mnemonicParsing="false" onAction="#textEncryptButton" prefHeight="26.0" prefWidth="76.0" text="Encrypt" />
|
||||
<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" text="Decrypt" />
|
||||
<Separator fx:id="textSeparator1" layoutX="7.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
|
||||
<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="187.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
|
||||
<Text fx:id="textAlgorithm" layoutX="194.0" layoutY="409.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" />
|
||||
<Button fx:id="textDecryptButton" layoutX="199.0" layoutY="340.0" mnemonicParsing="false" onAction="#textDecryptButton" prefHeight="26.0" prefWidth="76.0" text="Decrypt" />
|
||||
<Separator fx:id="textSeparator1" layoutX="7.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" />
|
||||
<Text fx:id="textAdvanced" layoutX="106.0" layoutY="386.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" textAlignment="CENTER" wrappingWidth="85.9" />
|
||||
<Separator fx:id="textSeparator2" layoutX="190.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" />
|
||||
<Text fx:id="textAlgorithm" layoutX="185.0" layoutY="409.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" textAlignment="CENTER" wrappingWidth="77.6" />
|
||||
<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" />
|
||||
<Separator fx:id="midSeparator1" layoutX="300.0" layoutY="35.0" orientation="VERTICAL" prefHeight="424.0" prefWidth="0.0" />
|
||||
<Text fx:id="fileEnDecryptText" layoutX="403.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="En- / decrypt Files" />
|
||||
<TextField fx:id="fileEnDecryptKeyEntry" layoutX="376.0" layoutY="64.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" promptText="Key" />
|
||||
<Button fx:id="fileEnDecryptFilesButton" layoutX="408.0" layoutY="97.0" mnemonicParsing="false" onAction="#fileEnDecryptChoose" text="Choose files..." />
|
||||
<Text fx:id="fileEnDecryptText" layoutX="384.0" layoutY="49.0" strokeType="OUTSIDE" strokeWidth="0.0" text="En- / decrypt Files" textAlignment="CENTER" wrappingWidth="135.9" />
|
||||
<TextField fx:id="fileEnDecryptKeyEntry" layoutX="374.0" layoutY="64.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="155.0" 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..." />
|
||||
<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">
|
||||
<content>
|
||||
<VBox fx:id="fileEnDecryptInputFiles" onDragDropped="#onFileEnDecryptDragNDrop" onDragOver="#onFileEnDecryptDragOver" prefHeight="105.0" prefWidth="282.0" />
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<Text fx:id="fileEncryptOutputFileText" layoutX="310.0" layoutY="261.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Encrypted 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" />
|
||||
<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" />
|
||||
<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" />
|
||||
<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" />
|
||||
<Button fx:id="fileEncrypt" layoutX="329.0" layoutY="314.0" mnemonicParsing="false" onAction="#fileEncryptButton" prefHeight="26.0" prefWidth="76.0" text="Encrypt" />
|
||||
<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="313.0" mnemonicParsing="false" onAction="#fileDecryptButton" text="Decrypt" />
|
||||
<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="109.0" />
|
||||
<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="485.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
|
||||
<Text fx:id="fileEnDecryptAlgorithm" layoutX="494.0" layoutY="409.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" />
|
||||
<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="fileEnDecryptStop" layoutX="417.0" layoutY="345.0" mnemonicParsing="false" onAction="#fileEnDecryptCancelButton" prefHeight="26.0" prefWidth="68.0" text="Cancel" />
|
||||
<Separator fx:id="fileEnDecryptSeparator1" layoutX="309.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" />
|
||||
<Text fx:id="fileEnDecryptAdvanced" layoutX="409.0" layoutY="387.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" textAlignment="CENTER" wrappingWidth="85.9" />
|
||||
<Separator fx:id="fileEnDecryptSeparator2" layoutX="489.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" />
|
||||
<Text fx:id="fileEnDecryptAlgorithm" layoutX="484.0" layoutY="409.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" textAlignment="CENTER" wrappingWidth="77.6" />
|
||||
<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" />
|
||||
<Separator fx:id="midSeparator2" layoutX="600.0" layoutY="35.0" orientation="VERTICAL" prefHeight="424.0" prefWidth="0.0" />
|
||||
<Text fx:id="fileDeleteText" layoutX="703.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Secure delete files" />
|
||||
<Button fx:id="fileEnDecryptFilesButton1" layoutX="708.0" layoutY="64.0" mnemonicParsing="false" onAction="#fileDeleteChoose" text="Choose files..." />
|
||||
<ScrollPane fx:id="fileDeleteInputScroll" hbarPolicy="NEVER" layoutX="608.0" layoutY="96.0" prefHeight="228.0" prefWidth="285.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" />
|
||||
<Button fx:id="fileDeleteChooseFilesButton" layoutX="616.0" layoutY="64.0" mnemonicParsing="false" onAction="#fileDeleteChooseFiles" prefHeight="26.0" prefWidth="120.0" 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" />
|
||||
<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>
|
||||
<VBox fx:id="fileDeleteInputFiles" onDragDropped="#onFileDeleteDragNDrop" onDragOver="#onFileDeleteDragOver" prefHeight="226.0" prefWidth="282.0" />
|
||||
<VBox fx:id="fileDeleteInputFiles" onDragDropped="#onFileDeleteDragNDrop" onDragOver="#onFileDeleteDragOver" prefHeight="226.0" prefWidth="283.0" />
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<Button fx:id="fileDeleteButton" layoutX="647.0" layoutY="339.0" mnemonicParsing="false" onAction="#fileDelete" text="Delete" />
|
||||
<Button fx:id="fileDeleteButton" layoutX="646.0" layoutY="339.0" mnemonicParsing="false" onAction="#fileDelete" prefWidth="68.0" text="Delete" />
|
||||
<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="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="109.0" />
|
||||
<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="781.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
|
||||
<Button fx:id="fileDeleteStop" layoutX="796.0" layoutY="339.0" mnemonicParsing="false" onAction="#fileDeleteCancelButton" prefWidth="68.0" text="Cancel" />
|
||||
<Separator fx:id="fileDeleteSeparator1" layoutX="610.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.0" />
|
||||
<Text fx:id="fileDeleteAdvanced" layoutX="709.0" layoutY="387.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" textAlignment="CENTER" wrappingWidth="85.9" />
|
||||
<Separator fx:id="fileDeleteSeparator2" layoutX="791.0" layoutY="379.0" prefHeight="8.0" prefWidth="103.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" />
|
||||
<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>
|
||||
</AnchorPane>
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |