diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java index 280ca40..6377528 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java @@ -34,10 +34,10 @@ public class CommandEncrypt implements TabExecutor { return false; } - EncryptionStyle encryptionStyle = arguments.length == 2 ? EncryptionStyle.getFromString(arguments[1]) : EncryptionStyle.SUBSTITUTION; + EncryptionStyle encryptionStyle = arguments.length == 2 ? EncryptionStyle.getFromString(arguments[1]) : EncryptionStyle.AES; // AES is the only reliable method for retaining the plaintext - if (BooksWithoutBorders.getConfiguration().useRealEncryption()) { + if (BooksWithoutBorders.getConfiguration().useRealEncryption() && !encryptionStyle.isRealEncryptionSupported()) { encryptionStyle = EncryptionStyle.AES; } @@ -132,10 +132,13 @@ public class CommandEncrypt implements TabExecutor { @NotNull protected List doTabCompletion(@NotNull String[] args, boolean groupEncrypt) { int argumentsCount = args.length; + boolean useRealEncryption = BooksWithoutBorders.getConfiguration().useRealEncryption(); List encryptionStyles = new ArrayList<>(); for (EncryptionStyle encryptionStyle : EncryptionStyle.values()) { - encryptionStyles.add(encryptionStyle.toString()); + if (!useRealEncryption || encryptionStyle.isRealEncryptionSupported()) { + encryptionStyles.add(encryptionStyle.toString()); + } } if (groupEncrypt) { @@ -150,9 +153,6 @@ public class CommandEncrypt implements TabExecutor { if (argumentsCount == 1) { return List.of(""); } else if (argumentsCount == 2) { - if (BooksWithoutBorders.getConfiguration().useRealEncryption()) { - return List.of(); - } return TabCompletionHelper.filterMatchingStartsWith(encryptionStyles, args[1]); } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/encryption/EncryptionStyle.java b/src/main/java/net/knarcraft/bookswithoutborders/encryption/EncryptionStyle.java index 5174826..c63b5bb 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/encryption/EncryptionStyle.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/encryption/EncryptionStyle.java @@ -10,38 +10,53 @@ public enum EncryptionStyle { /** * Possibly lossy encryption using DNA codons */ - DNA("dna"), + DNA("dna", false), /** * A simple cipher using the key to substitute one character for another */ - SUBSTITUTION("substitution"), + SUBSTITUTION("substitution", true), /** * A military-grade encryption cypher */ - AES("aes"), + AES("aes", true), /** * An unbreakable encryption method assuming the key is completely random and never used more than once, ever */ - ONE_TIME_PAD("onetimepad"), + ONE_TIME_PAD("onetimepad", true), /** * Just a way of using magic text to make text illegible */ - MAGIC("magic"), + MAGIC("magic", false), ; private final String name; + private final boolean realEncryptionSupported; /** * Instantiates a new encryption style * - * @param name

The human-readable encryption style name

+ * @param name

The human-readable encryption style name

+ * @param realEncryptionSupported

Whether the encryption style can be used for real encryption

*/ - EncryptionStyle(@NotNull String name) { + EncryptionStyle(@NotNull String name, boolean realEncryptionSupported) { this.name = name; + this.realEncryptionSupported = realEncryptionSupported; + } + + /** + * Gets whether this encryption style supports real encryption + * + *

Real encryption means that only the cypher text is stored on disk, so the server owner cannot simply check the + * contents of encrypted books.

+ * + * @return

True if this encryption style supports real encryption

+ */ + public boolean isRealEncryptionSupported() { + return this.realEncryptionSupported; } /** @@ -57,7 +72,7 @@ public enum EncryptionStyle { return style; } } - return SUBSTITUTION; + return AES; } @Override diff --git a/src/main/java/net/knarcraft/bookswithoutborders/encryption/OneTimePad.java b/src/main/java/net/knarcraft/bookswithoutborders/encryption/OneTimePad.java index ad7a362..f73bd8b 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/encryption/OneTimePad.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/encryption/OneTimePad.java @@ -1,5 +1,6 @@ package net.knarcraft.bookswithoutborders.encryption; +import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,12 +27,12 @@ public class OneTimePad implements Encryptor { @Override public @Nullable String encryptText(@NotNull String input) { - return oneTimePad(input); + return oneTimePad(input, true); } @Override public @Nullable String decryptText(@NotNull String input) { - return oneTimePad(input); + return oneTimePad(input, false); } /** @@ -40,11 +41,16 @@ public class OneTimePad implements Encryptor { *

The one time pad encryption is very secure, and encryption works just like decryption, but is vulnerable if * the same key is used more than once.

* - * @param input

The input to encrypt/decrypt

+ * @param input

The input to encrypt/decrypt

+ * @param encrypt

Whether to encrypt or decrypt the input

* @return

The encrypted/decrypted output

*/ @NotNull - public String oneTimePad(@NotNull String input) { + public String oneTimePad(@NotNull String input, boolean encrypt) { + if (!encrypt) { + input = new String(EncryptionHelper.hexStringToByteArray(input), StandardCharsets.UTF_8); + } + String longKey; try { final MessageDigest digest = MessageDigest.getInstance("SHA3-256"); @@ -58,7 +64,12 @@ public class OneTimePad implements Encryptor { for (int i = 0; i < input.length(); i++) { output.append((char) (input.charAt(i) ^ longKey.charAt(i % longKey.length()))); } - return output.toString(); + + if (encrypt) { + return EncryptionHelper.bytesToHex(output.toString().getBytes(StandardCharsets.UTF_8)); + } else { + return output.toString(); + } } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/encryption/SubstitutionCipher.java b/src/main/java/net/knarcraft/bookswithoutborders/encryption/SubstitutionCipher.java index 24396a0..68e7b62 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/encryption/SubstitutionCipher.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/encryption/SubstitutionCipher.java @@ -1,9 +1,11 @@ package net.knarcraft.bookswithoutborders.encryption; +import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.util.StringTokenizer; /** @@ -49,6 +51,10 @@ public class SubstitutionCipher implements Encryptor { return output.toString(); } + if (!encrypt) { + input = new String(EncryptionHelper.hexStringToByteArray(input), StandardCharsets.UTF_8); + } + // converts each number in the key to an integer and adds to an array int[] offsetArray = getOffsetArray(this.key); @@ -68,7 +74,12 @@ public class SubstitutionCipher implements Encryptor { offsetPosition = 0; } } - return output.toString(); + + if (encrypt) { + return EncryptionHelper.bytesToHex(output.toString().getBytes(StandardCharsets.UTF_8)); + } else { + return output.toString(); + } } /** diff --git a/src/main/resources/strings.yml b/src/main/resources/strings.yml index 3a702ba..5d816f1 100644 --- a/src/main/resources/strings.yml +++ b/src/main/resources/strings.yml @@ -12,7 +12,7 @@ en: SUCCESS_PAGE_DELETED: "Page deleted!" SUCCESS_BOOK_LOADED: "Book created!" SUCCESS_MIGRATION_STARTED: "Starting book migration..." - SUCCESS_RELOADED: "BooksWithoutBorders configuration reloaded!" + SUCCESS_RELOADED: "Configuration, books and language strings reloaded!" SUCCESS_SAVED: "Book Saved as &e\"{fileName}\"&r" ACTION_COPY: "copy" ACTION_CLEAR: "clear" diff --git a/src/test/java/net/knarcraft/bookswithoutborders/GenenCryptTest.java b/src/test/java/net/knarcraft/bookswithoutborders/GenenCryptTest.java deleted file mode 100644 index 46ad6c6..0000000 --- a/src/test/java/net/knarcraft/bookswithoutborders/GenenCryptTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.knarcraft.bookswithoutborders; - -import net.knarcraft.bookswithoutborders.encryption.GenenCrypt; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class GenenCryptTest { - - @Test - public void encryptDecryptTest() { - GenenCrypt gc = new GenenCrypt("Another Key"); - gc.printCodonTable(); - String encrypted = gc.encryptText("Hello World!"); - - assertNotNull(encrypted); - - assertEquals("HELLO WORLD!", gc.decryptText(encrypted)); - } - -} diff --git a/src/test/java/net/knarcraft/bookswithoutborders/encryption/AESTest.java b/src/test/java/net/knarcraft/bookswithoutborders/encryption/AESTest.java index 538d959..b9fac51 100644 --- a/src/test/java/net/knarcraft/bookswithoutborders/encryption/AESTest.java +++ b/src/test/java/net/knarcraft/bookswithoutborders/encryption/AESTest.java @@ -13,21 +13,16 @@ public class AESTest { String plainText = "Flåklypa"; String password = "TqOZdpY9RjjjVE9JjCWVecUYObv5MYidByrpI3cxjoY="; - System.out.println("Plaintext: " + plainText); - System.out.println("Encryption password: " + password); - AESConfiguration configuration = new AESConfiguration(new byte[]{-85, 103, -82, 71, 119, 28, 73, -75, -81, 102, -127, -125, -8, -75, 81, -111}, new byte[]{(byte) 104, -42, 63, 31, -120, -2, 14, -119, 35, 122, 109, -64, 122, 117, 33, -85}, password); AES aes = new AES(configuration); String cypherText = aes.encryptText(plainText); - System.out.println("Cypher text: " + cypherText); assertNotNull(cypherText); assertNotEquals(plainText, cypherText); String decrypted = aes.decryptText(cypherText); - System.out.println("Decrypted: " + decrypted); assertEquals(plainText, decrypted); } diff --git a/src/test/java/net/knarcraft/bookswithoutborders/encryption/GenenCryptTest.java b/src/test/java/net/knarcraft/bookswithoutborders/encryption/GenenCryptTest.java index c40c34b..396f075 100644 --- a/src/test/java/net/knarcraft/bookswithoutborders/encryption/GenenCryptTest.java +++ b/src/test/java/net/knarcraft/bookswithoutborders/encryption/GenenCryptTest.java @@ -12,8 +12,12 @@ public class GenenCryptTest { @Test public void encryptDecryptTest() { String encryptionKey = EncryptionHelper.getNumberKeyFromStringKey("My secret password!"); - String plaintext = "Very secret &4colored&r message."; + String plaintext = "Very secret &4colored&r message. That might be quite long. Of course, the length might " + + "cause problems, especially as the gene encryption requires several characters for every encrypted " + + "character. Also, the hexadecimal representation of the original text is encrypted. It is unknown if " + + "that might represent an increase in length."; GenenCrypt genenCrypt = new GenenCrypt(encryptionKey); + genenCrypt.printCodonTable(); String cypherText = genenCrypt.encryptText(plaintext); diff --git a/src/test/java/net/knarcraft/bookswithoutborders/encryption/OneTimePadTest.java b/src/test/java/net/knarcraft/bookswithoutborders/encryption/OneTimePadTest.java index 75f3aae..e4541db 100644 --- a/src/test/java/net/knarcraft/bookswithoutborders/encryption/OneTimePadTest.java +++ b/src/test/java/net/knarcraft/bookswithoutborders/encryption/OneTimePadTest.java @@ -10,8 +10,9 @@ public class OneTimePadTest { @Test public void oneTimePadTest() { - String plaintext = "Very secret text that should be kept secret"; - String key = "Very secret key!"; + String plaintext = "Very secret text that should be kept secret. It should be noted that several characters, " + + "like !\"#¤%&/()=?`§|@£${[]}'*,.-;:_<>µ need to be tested. Also foreign characters, like: øæåØÆÅ"; + String key = "Very secret key that you will never guess!¤%&/"; OneTimePad oneTimePad = new OneTimePad(key); String cypherText = oneTimePad.encryptText(plaintext); diff --git a/src/test/java/net/knarcraft/bookswithoutborders/encryption/SubstitutionCipherTest.java b/src/test/java/net/knarcraft/bookswithoutborders/encryption/SubstitutionCipherTest.java index 54bf4ce..8c0b0c8 100644 --- a/src/test/java/net/knarcraft/bookswithoutborders/encryption/SubstitutionCipherTest.java +++ b/src/test/java/net/knarcraft/bookswithoutborders/encryption/SubstitutionCipherTest.java @@ -11,8 +11,9 @@ public class SubstitutionCipherTest { @Test public void encryptDecryptTest() { - String plaintext = "Very secret text that should be kept secret"; - String integerKey = EncryptionHelper.getNumberKeyFromStringKey("Very secret key!"); + String plaintext = "Very secret text that should be kept secret. It should be noted that several characters, " + + "like !\"#¤%&/()=?`§|@£${[]}'*,.-;:_<>µ need to be tested. Also foreign characters, like: øæåØÆÅ"; + String integerKey = EncryptionHelper.getNumberKeyFromStringKey("Very secret key that you will never guess!¤%&/"); SubstitutionCipher substitutionCipher = new SubstitutionCipher(integerKey); String cypherText = substitutionCipher.encryptText(plaintext);