diff --git a/.classpath b/.classpath index c8b1995..f8967fe 100644 --- a/.classpath +++ b/.classpath @@ -1,11 +1,11 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/.project b/.project index 0282667..f670734 100644 --- a/.project +++ b/.project @@ -1,17 +1,17 @@ - - - CryptoKnight - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - + + + Cryptoknight + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/new b/.settings/new deleted file mode 100644 index 8b13789..0000000 --- a/.settings/new +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/Encryptor.java b/src/Encryptor.java index 64d0ff1..c68aab6 100644 --- a/src/Encryptor.java +++ b/src/Encryptor.java @@ -1,3 +1,4 @@ + import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -25,10 +26,12 @@ import org.bouncycastle.crypto.engines.Shacal2Engine; import org.bouncycastle.crypto.engines.ThreefishEngine; import org.bouncycastle.crypto.engines.TwofishEngine; -import org.bouncycastle.crypto.modes.CBCBlockCipher; +import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.paddings.BlockCipherPadding; import org.bouncycastle.crypto.paddings.PKCS7Padding; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; +import org.bouncycastle.crypto.modes.AEADBlockCipher; +import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.TweakableBlockCipherParameters; @@ -37,12 +40,12 @@ public class Encryptor { private int blockSize; private byte[] ivData; - private BlockCipherPadding padding; private SecretKeyFactory factory; private String salt; private KeySpec spec; private SecretKey tmp; private KeyParameter keyParam; + private BlockCipherPadding padding; private Object[] Algs = {new AESEngine(), null, new TwofishEngine(), new CamelliaEngine(), new SerpentEngine(), new CAST6Engine(), new RC6Engine(), null, new Shacal2Engine()}; @@ -72,7 +75,7 @@ public void setParameters(int KeySize, int alg) throws NoSuchAlgorithmException, break; case 256: - Algs[1] = new RijndaelEngine(KeySize); + Algs[1] = new RijndaelEngine(128); Algs[7] = new ThreefishEngine(KeySize); break; @@ -81,7 +84,8 @@ public void setParameters(int KeySize, int alg) throws NoSuchAlgorithmException, break; } - padding = new PKCS7Padding(); + padding = new PKCS7Padding(); + } public void setEncParameters(int alg, String pwd, int KeySize, String mode) throws NoSuchAlgorithmException, InvalidKeySpecException @@ -175,14 +179,29 @@ public byte[] CBCEncrypt(byte[] input, int alg) throws NoSuchAlgorithmException, } - BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher((BlockCipher) Algs[alg]), padding); - cipher.reset(); - cipher.init(true, cipherParams); + byte[] output; + if (alg == 7 || alg == 8) + { + BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher((BlockCipher) Algs[alg]), padding); + cipher.reset(); + cipher.init(true, cipherParams); + output = new byte[cipher.getOutputSize(input.length)]; + int bytesWrittenOut = cipher.processBytes(input, 0, input.length, output, 0); + bytesWrittenOut += cipher.doFinal(output, bytesWrittenOut); + } + + else + { + AEADBlockCipher cipher = new GCMBlockCipher((BlockCipher) Algs[alg]); + cipher.reset(); + cipher.init(true, cipherParams); + output = new byte[cipher.getOutputSize(input.length)]; + + int bytesWrittenOut = cipher.processBytes(input, 0, input.length, output, 0); + bytesWrittenOut += cipher.doFinal(output, bytesWrittenOut); + } - byte[] output = new byte[cipher.getOutputSize(input.length)]; - int bytesWrittenOut = cipher.processBytes(input, 0, input.length, output, 0); - bytesWrittenOut += cipher.doFinal(output, bytesWrittenOut); byte[] bytesAll = new byte[ivData.length + output.length + salt.getBytes().length]; System.arraycopy(ivData, 0, bytesAll, 0, ivData.length); @@ -215,14 +234,34 @@ public byte[] CBCDecrypt(byte[] Encrypted, int alg) throws UnsupportedEncodingEx break; } - BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher((BlockCipher) Algs[alg]), padding); - cipher.reset(); - cipher.init(false, cipherParams); + byte[] output; + int bytesWrittenin; + if (alg == 7 || alg == 8) + { + BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher((BlockCipher) Algs[alg]), padding); + cipher.reset(); + cipher.init(false, cipherParams); + + output = new byte[cipher.getOutputSize(rawEnc.length - blockSize/8)]; + + bytesWrittenin = cipher.processBytes(rawEnc, blockSize/8, rawEnc.length - blockSize/8, output, 0); + bytesWrittenin += cipher.doFinal(output, bytesWrittenin); + + } - byte[] output = new byte[cipher.getOutputSize(rawEnc.length - blockSize/8)]; + else + { + AEADBlockCipher cipher = new GCMBlockCipher((BlockCipher) Algs[alg]); + cipher.reset(); + cipher.init(false, cipherParams); + + output = new byte[cipher.getOutputSize(rawEnc.length - blockSize/8)]; + + bytesWrittenin = cipher.processBytes(rawEnc, blockSize/8, rawEnc.length - blockSize/8, output, 0); + bytesWrittenin += cipher.doFinal(output, bytesWrittenin); + + } - int bytesWrittenin = cipher.processBytes(rawEnc, blockSize/8, rawEnc.length - blockSize/8, output, 0); - bytesWrittenin += cipher.doFinal(output, bytesWrittenin); byte[] Dec = new byte[bytesWrittenin]; System.arraycopy(output, 0, Dec, 0, bytesWrittenin); diff --git a/src/GUI.java b/src/GUI.java index 60a21d9..e2594b8 100644 --- a/src/GUI.java +++ b/src/GUI.java @@ -110,7 +110,7 @@ public void ConstructGUI() this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - this.setTitle("CryptoKnight 0.1"); + this.setTitle("CryptoKnight 0.0.2"); ListenForButton L4B = new ListenForButton(); @@ -519,7 +519,7 @@ public void ConstructGUI() HRow2.setLayout(new BoxLayout(HRow2, BoxLayout.Y_AXIS)); FAQText = new JTextArea(18, 28); - FAQText.setText("Frequently Asked Questions:\n\nQ: Encryption doesn't work with keys larger than 192 bit! Why?\nA: Due to a ridiculous limitation imposed by Java, you can only use 192 (sometimes 128) bit keys or below. To overcome this, you need to replace the stock security policy files with the unlimited ones provided for free by Oracle. Just google JCE_policy-(your java version number for example 7 or 8).zip, download it, and unzip the content of the included UnlimitedJCEPolicyJDK folder to the directory containing your java security policy files. for example, if you're on windowse, go to the drive where you installed java jre or jdk, and the target directory would be java/jre (or jdk)/lib/security/.\n\nQ: Does this program store my passwords?\nA: No, because it doesn't need to. Before encrypting anything, a key (which is more complicated than just a password) is generated, and the password is part of the key parameters. In other words, the password becomes part of what converts your nice plain text to meaningless gibberish. When you try to decrypt a ciphertext, the decryption password is used to construct key parameters, and if all is good, those parameters convert the nonsense back to readable plain text.\n\nQ: Why doesn't this app provide a password vault?\nA: A password vault is just an encrypted file containing a table of usernames and corresponding passwords. You can easily create a word/excel file, store your passwords in it, and encrypt it using one of the provided algorithms.\n\nQ: Isn't AES and Rijndael one and the same?\nA: No. Rijndael is ablock cipher that supports 128 192 256 bit key size, and 128 192 224 and 256 block sizes. AES is a subset of Rijndael that accepts the same key sizes, but has a fixed block size (128 bit). To offer more flexibility, the app offers both.\n\nQ: Is there a way to recover forgotton passwords?\nA: Unfortunately, there is no way this program can tell who is trying to access the data. As a result there it is impossible to give anyone a chance to recover lost passwords without introducing a backdoor. If you forgot your password, any data encrypted with it is lost forever.\n\nQ: What is 'Quick Mode'?\nA: Normally, the program uses SHA-512 hashing when generating secret keys. By checking Quick Mode you opt to use SHA-256, leading to quicker encryption/decryption. Theoretically, that makes attacks on your keys more affordable, but I still can't imagine a successful attack against them. However, keep in mind that data encrypted with Quick Mode, can only be decrypted with the same mode, and vice versa.\n\nQ: Which encryption algorithm is the most secure?\nA: This question gets asked a lot, short answer: none of the offered algorithms has ever been compromised. Long version: exhausting half the key space of even a 128 bit key os a symmetric cipher would take longer than the life-time of the universe. The most serious threat to your data is a weak password, so choose your password wisely.\n\nQ: What exactly does the password booster do?\nA: This feature is meant to help users generate reproducile, yet powerful passwords. I would've preffered to keep that secret, but since this app is open source, anyone can get the source code and find out themselves. First the password booster calculates an scrypt hash of your password, then it encodes that hashed pass in base64, third step is multiplying the base64 string by a multiplication key provided by the user, afterwards, 2 pseudorandom numbers p1 and p2 are generated based on the random seed (also given by the user) and the specified password length, and used as slice borders for a substring of the huge base64 string from step 3. Finally 4 pseudorandom positions are generated based on the same seed, and 4 special characters are inserted at those positions. The same multiplication key, seed, and length always give the same result with any one password."); + FAQText.setText("Frequently Asked Questions:\n\nQ: Encryption doesn't work with keys larger than 192 bit! Why?\nA: Due to a ridiculous limitation imposed by Java, you can only use 192 (sometimes 128) bit keys or below. To overcome this, you need to replace the stock security policy files with the unlimited ones provided for free by Oracle. Just google JCE_policy-(your java version number for example 7 or 8).zip, download it, and unzip the content of the included UnlimitedJCEPolicyJDK folder to the directory containing your java security policy files. for example, if you're on windowse, go to the drive where you installed java jre or jdk, and the target directory would be java/jre (or jdk)/lib/security/.\n\nQ: Does this program store my passwords?\nA: No, because it doesn't need to. Before encrypting anything, a key (which is more complex than just a password) is generated, and the password is part of the key parameters. In other words, the password is a part of what turns your nice plain text into meaningless gibberish. When you try to decrypt a ciphertext, the decryption password is used to construct the key parameters, and if all is good, those parameters turn the gibberish back into readable plain text.\n\nQ: Why doesn't this app provide a password vault?\nA: A password vault is just an encrypted file containing a table of usernames and corresponding passwords. You can easily create a word/excel file, store your passwords in it, and encrypt it using one of the provided algorithms.\n\nQ: Isn't AES and Rijndael one and the same?\nA: No. Rijndael is a block cipher that supports 128, 192, and 256 bit key size, and 128, 192, 224, and 256 block sizes. AES is a subset of Rijndael that accepts the same key sizes, but has a fixed block size (128 bit). To offer more flexibility, this app offers both.\n\nQ: Is there a way to recover a forgotton password?\nA: Unfortunately, the app has no way of telling who is trying to access the data without a valid password, as a result it is impossible to add password recovery without introducing a backdoor. If you forgot your password, any data encrypted with it is lost forever.\n\nQ: What is 'Quick Mode'?\nA: Normally, the program uses SHA-512 hashing when generating secret keys. By checking Quick Mode you opt to use SHA-256, leading to quicker encryption/decryption. Theoretically, this makes attacks on your keys more affordable, but I still can't imagine a successful attack against them. However, keep in mind that data encrypted with Quick Mode, can only be decrypted with the same mode, and vice versa.\n\nQ: Which encryption algorithm is the most secure?\nA: This question gets asked a lot, short answer: none of the offered algorithms has ever been compromised. Long version: exhausting half the key space of even a 128 bit key would take longer than the lifetime of the universe. The most serious threat to your data is a weak password, so choose your password wisely.\n\nQ: What exactly does the password booster do?\nA: This feature is meant to help users generate reproducile, yet powerful passwords. I would've preffered to keep it secret, but since this app is open source, anyone can read the source code and find out for themselves. First the password booster calculates an scrypt hash of your password, then it encodes that hashed pass in base64, third step is multiplying the base64 string by a multiplication key provided by the user, afterwards, 2 pseudorandom numbers p1 and p2 are generated based on a random seed (also given by the user) and the specified password length, and used as slice borders for a substring of the huge base64 string from step 3. Finally 4 pseudorandom positions are generated based on the same seed, and 4 special characters are inserted at these positions. The same multiplication key, seed, and length always give the same result with any one password."); FAQText.setLineWrap(true); FAQText.setWrapStyleWord(true); FAQText.setEditable(false); @@ -842,6 +842,8 @@ public void run() } FileEncrypt.wipeFile(InputFile.getText()); + long elapsed = System.nanoTime() - start; + FReport.setText(OpRes + "\n\nTotal time: " + elapsed/1e9 + " seconds."); JOptionPane.showMessageDialog(GUI.this, "Input file wiped successfully", "Success!", JOptionPane.INFORMATION_MESSAGE); } catch (FileNotFoundException e) @@ -876,12 +878,7 @@ public void run() OpRes = e.getMessage(); } } - - long elapsed = System.nanoTime() - start; - - FReport.setText(OpRes + "\n\nTotal time: " + elapsed/1e9 + " seconds."); - }//end of run body @@ -929,6 +926,8 @@ public void run() } FileEncrypt.wipeFile(InputFile.getText()); + long elapsed = System.nanoTime() - start; + FReport.setText(OpRes + "\n\nTotal time: " + elapsed/1e9 + " seconds."); JOptionPane.showMessageDialog(GUI.this, "Input file wiped successfully", "Success!", JOptionPane.INFORMATION_MESSAGE); } catch (FileNotFoundException e) @@ -963,9 +962,6 @@ public void run() OpRes = e.getMessage(); } } - long elapsed = System.nanoTime() - start; - - FReport.setText(OpRes + "\n\nTotal time: " + elapsed/1e9 + " seconds."); }//end of run body diff --git a/src/PwdGen.java b/src/PwdGen.java index e38eb09..c43e507 100644 --- a/src/PwdGen.java +++ b/src/PwdGen.java @@ -11,7 +11,7 @@ public class PwdGen public static String BoostPass(String OrigPass, int multKey, int RandSeed, int len) throws NoSuchAlgorithmException { - String HashedPass = HashFactory.SCryptHash(OrigPass, 13, 128, 256, 50, 0); + String HashedPass = HashFactory.SCryptHash(OrigPass, 64, 192, 256, 50, 0); String EncPass = Base64.encodeBase64String(HashedPass.getBytes()); String ExtPass = ""; @@ -199,4 +199,4 @@ private static StringBuilder List2StringBuilder(List l) return sb; } -} \ No newline at end of file +}