diff --git a/eu.steffo.cleaver.iml b/eu.steffo.cleaver.iml
index 5770e2e..971f913 100644
--- a/eu.steffo.cleaver.iml
+++ b/eu.steffo.cleaver.iml
@@ -6,6 +6,7 @@
+
diff --git a/examples/loremipsum.txt.c1 b/examples/loremipsum.txt.c1
deleted file mode 100644
index a55d884..0000000
Binary files a/examples/loremipsum.txt.c1 and /dev/null differ
diff --git a/examples/loremipsum.txt.c2 b/examples/loremipsum.txt.c2
deleted file mode 100644
index 1fcb998..0000000
Binary files a/examples/loremipsum.txt.c2 and /dev/null differ
diff --git a/examples/loremipsum.txt.c3 b/examples/loremipsum.txt.c3
deleted file mode 100644
index 64e357b..0000000
Binary files a/examples/loremipsum.txt.c3 and /dev/null differ
diff --git a/examples/loremipsum.txt.c4 b/examples/loremipsum.txt.c4
deleted file mode 100644
index b2669ac..0000000
Binary files a/examples/loremipsum.txt.c4 and /dev/null differ
diff --git a/examples/loremipsum.txt.c5 b/examples/loremipsum.txt.c5
deleted file mode 100644
index 1601410..0000000
Binary files a/examples/loremipsum.txt.c5 and /dev/null differ
diff --git a/examples/loremipsum.txt.c6 b/examples/loremipsum.txt.c6
deleted file mode 100644
index 8b3e07c..0000000
Binary files a/examples/loremipsum.txt.c6 and /dev/null differ
diff --git a/examples/loremipsum.txt.c7 b/examples/loremipsum.txt.c7
deleted file mode 100644
index 38c3caf..0000000
Binary files a/examples/loremipsum.txt.c7 and /dev/null differ
diff --git a/examples/loremipsum.txt.c8 b/examples/loremipsum.txt.c8
deleted file mode 100644
index 2b0582b..0000000
Binary files a/examples/loremipsum.txt.c8 and /dev/null differ
diff --git a/examples/loremipsum.txt.c9 b/examples/loremipsum.txt.c9
deleted file mode 100644
index 33e43a2..0000000
Binary files a/examples/loremipsum.txt.c9 and /dev/null differ
diff --git a/examples/loremipsum.txt.chp b/examples/loremipsum.txt.chp
deleted file mode 100644
index 4816b80..0000000
--- a/examples/loremipsum.txt.chp
+++ /dev/null
@@ -1 +0,0 @@
-loremipsum.txt
\ No newline at end of file
diff --git a/src/eu/steffo/cleaver/gui/CleaverFrame.java b/src/eu/steffo/cleaver/gui/CleaverFrame.java
index 144091b..b15ec90 100644
--- a/src/eu/steffo/cleaver/gui/CleaverFrame.java
+++ b/src/eu/steffo/cleaver/gui/CleaverFrame.java
@@ -109,7 +109,7 @@ public class CleaverFrame extends JFrame {
@Override
public void actionPerformed(ActionEvent e) {
for(Job job : jobs) {
- if(job.getProgress() instanceof NotStartedProgress)
+ if(job.getState() == Thread.State.NEW)
{
job.start();
}
diff --git a/src/eu/steffo/cleaver/logic/ChopJob.java b/src/eu/steffo/cleaver/logic/ChopJob.java
index 444337e..3d5efcd 100644
--- a/src/eu/steffo/cleaver/logic/ChopJob.java
+++ b/src/eu/steffo/cleaver/logic/ChopJob.java
@@ -98,7 +98,7 @@ public class ChopJob extends Job {
outputStream = new SplitFileOutputStream(file.getAbsolutePath(), splitConfig.getPartSize());
}
else {
- outputStream = new FileOutputStream(String.format("%s.c00", file.getAbsolutePath()));
+ outputStream = new FileOutputStream(String.format("%s.c0", file.getAbsolutePath()));
}
if(compressConfig != null) {
@@ -160,6 +160,7 @@ public class ChopJob extends Job {
this.setProgress(new FinishedProgress());
} catch (Throwable e) {
+ e.printStackTrace();
this.setProgress(new ErrorProgress(e));
}
}
diff --git a/src/eu/steffo/cleaver/logic/StitchJob.java b/src/eu/steffo/cleaver/logic/StitchJob.java
index eaa3334..c95623a 100644
--- a/src/eu/steffo/cleaver/logic/StitchJob.java
+++ b/src/eu/steffo/cleaver/logic/StitchJob.java
@@ -193,7 +193,7 @@ public class StitchJob extends Job {
inputStream = new SplitFileInputStream(resultFile.getPath(), splitConfig.getPartSize());
}
else {
- inputStream = new FileInputStream(String.format("%s.c00", resultFile.getAbsolutePath()));
+ inputStream = new FileInputStream(String.format("%s.c0", resultFile.getAbsolutePath()));
}
if (compressConfig != null) {
@@ -201,7 +201,7 @@ public class StitchJob extends Job {
}
if (cryptConfig != null) {
- inputStream = new CryptInputStream(inputStream);
+ inputStream = new CryptInputStream(inputStream, cryptConfig.getKey());
}
//Pipe everything to the output
@@ -220,6 +220,7 @@ public class StitchJob extends Job {
this.setProgress(new FinishedProgress());
} catch (Throwable e) {
+ e.printStackTrace();
this.setProgress(new ErrorProgress(e));
}
}
diff --git a/src/eu/steffo/cleaver/logic/crypt/CryptInputStream.java b/src/eu/steffo/cleaver/logic/crypt/CryptInputStream.java
index 0995979..9049393 100644
--- a/src/eu/steffo/cleaver/logic/crypt/CryptInputStream.java
+++ b/src/eu/steffo/cleaver/logic/crypt/CryptInputStream.java
@@ -1,14 +1,112 @@
package eu.steffo.cleaver.logic.crypt;
import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
import java.io.FilterInputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
public class CryptInputStream extends FilterInputStream {
+ private Cipher cipher;
- public CryptInputStream(InputStream in) {
- super(in);
+ /**
+ * @return The algorithm used for the encryption.
+ */
+ public String getAlgorithm() {
+ return "AES";
}
- //TODO: This doesn't do anything... yet.
+ /**
+ * @return The mode of operation used for the encryption.
+ */
+ public String getModeOfOperation() {
+ return "CFB8";
+ }
+
+ /**
+ * @return The padding used for the encryption.
+ */
+ public String getPadding() {
+ return "PKCS5Padding";
+ }
+
+ /**
+ * @return The secret key algorithm used in the generation of the final key.
+ */
+ public String getKeyAlgorithm() {
+ return "PBKDF2WithHmacSHA1";
+ }
+
+ /**
+ * @return The full transformation string as required by {@link Cipher#getInstance(String)}.
+ */
+ public String getTransformationString() {
+ return String.format("%s/%s/%s", getAlgorithm(), getModeOfOperation(), getPadding());
+ }
+
+
+ public CryptInputStream(InputStream in, String key) throws InvalidKeyException {
+ super(in);
+
+ //Setup the cipher object
+ try {
+ cipher = Cipher.getInstance(getTransformationString());
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+ //Should never happen, as it's predefined
+ e.printStackTrace();
+ return;
+ }
+
+ //Create the salt
+ byte[] salt = new byte[8];
+ SecureRandom secureRandom = new SecureRandom();
+ secureRandom.nextBytes(salt);
+
+ //Create the KeySpec
+ //Using the recommended 65536 as iteration count
+ KeySpec spec = new PBEKeySpec(key.toCharArray(), salt, 65536, 256);
+
+ SecretKeyFactory factory;
+ try {
+ factory = SecretKeyFactory.getInstance(getKeyAlgorithm());
+ } catch (NoSuchAlgorithmException e) {
+ //Should never happen, as it's predefined
+ e.printStackTrace();
+ return;
+ }
+
+ //Create the pbkdf secret key
+ SecretKey pbkdf;
+ try {
+ pbkdf = factory.generateSecret(spec);
+ } catch (InvalidKeySpecException e) {
+ //Should never happen, as it's predefined
+ e.printStackTrace();
+ return;
+ }
+
+ //"Convert" the secret key to a AES secret key
+ SecretKey aes = new SecretKeySpec(pbkdf.getEncoded(), getAlgorithm());
+
+ //Init the cipher instance
+ cipher.init(Cipher.DECRYPT_MODE, aes);
+ }
+
+ @Override
+ public int read() throws IOException {
+ int encryptedInt = super.read();
+ byte[] encryptedByte = new byte[1];
+ encryptedByte[0] = (byte)encryptedInt;
+ byte[] decryptedByte = cipher.update(encryptedByte);
+ return decryptedByte[0];
+ }
}
diff --git a/src/eu/steffo/cleaver/logic/crypt/CryptOutputStream.java b/src/eu/steffo/cleaver/logic/crypt/CryptOutputStream.java
index a2913e1..ae7eec3 100644
--- a/src/eu/steffo/cleaver/logic/crypt/CryptOutputStream.java
+++ b/src/eu/steffo/cleaver/logic/crypt/CryptOutputStream.java
@@ -4,68 +4,119 @@ import eu.steffo.cleaver.errors.ProgrammingError;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
public class CryptOutputStream extends FilterOutputStream {
private Cipher cipher;
- private final String algorithm;
- private final String modeOfOperation;
- private final String padding;
-
+ /**
+ * @return The algorithm used for the encryption.
+ */
public String getAlgorithm() {
- return algorithm;
+ return "AES";
}
+ /**
+ * @return The mode of operation used for the encryption.
+ */
public String getModeOfOperation() {
- return modeOfOperation;
+ return "CFB8";
}
+ /**
+ * @return The padding used for the encryption.
+ */
public String getPadding() {
- return padding;
+ return "PKCS5Padding";
}
+ /**
+ * @return The secret key algorithm used in the generation of the final key.
+ */
+ public String getKeyAlgorithm() {
+ return "PBKDF2WithHmacSHA1";
+ }
+
+ /**
+ * @return The full transformation string as required by {@link Cipher#getInstance(String)}.
+ */
public String getTransformationString() {
- return String.format("%s/%s/%s", algorithm, modeOfOperation, padding);
+ return String.format("%s/%s/%s", getAlgorithm(), getModeOfOperation(), getPadding());
}
- public CryptOutputStream(OutputStream out, String key, String algorithm, String modeOfOperation, String padding) throws ProgrammingError {
+ /**
+ * Create a new CryptOutputStream with default {@link Cipher} parameters.
+ * (AES algorithm in operation mode CFB8 with PKCS5 padding)
+ *
+ * Does not use this as {@literal try} and {@literal catch} are not supported.
+ *
+ * @param out The {@link OutputStream} to connect this {@link FilterOutputStream} to.
+ * @param key The desired encryption key.
+ */
+ public CryptOutputStream(OutputStream out, String key) throws InvalidKeyException {
super(out);
- this.algorithm = algorithm;
- this.modeOfOperation = modeOfOperation;
- this.padding = padding;
-
//Setup the cipher object
try {
cipher = Cipher.getInstance(getTransformationString());
- } catch (NoSuchAlgorithmException e) {
- // This should never happen.
- throw new ProgrammingError("Invalid algor specified in the CryptOutputStream.");
- } catch (NoSuchPaddingException e) {
- // This should never happen.
- throw new ProgrammingError("Invalid padding specified in the CryptOutputStream.");
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+ //Should never happen, as it's predefined
+ e.printStackTrace();
+ return;
}
- try {
- cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), this.algorithm));
- } catch (InvalidKeyException e) {
- // This should never happen.
- throw new ProgrammingError("Invalid key specified in the CryptOutputStream.");
- }
- }
- public CryptOutputStream(OutputStream out, String key) throws ProgrammingError {
- this(out, key, "AES", "CBC", "PKCS5Padding");
+ //Create the salt
+ byte[] salt = new byte[8];
+ SecureRandom secureRandom = new SecureRandom();
+ secureRandom.nextBytes(salt);
+
+ //Create the KeySpec
+ //Using the recommended 65536 as iteration count
+ KeySpec spec = new PBEKeySpec(key.toCharArray(), salt, 65536, 256);
+
+ SecretKeyFactory factory;
+ try {
+ factory = SecretKeyFactory.getInstance(getKeyAlgorithm());
+ } catch (NoSuchAlgorithmException e) {
+ //Should never happen, as it's predefined
+ e.printStackTrace();
+ return;
+ }
+
+ //Create the pbkdf secret key
+ SecretKey pbkdf;
+ try {
+ pbkdf = factory.generateSecret(spec);
+ } catch (InvalidKeySpecException e) {
+ //Should never happen, as it's predefined
+ e.printStackTrace();
+ return;
+ }
+
+ //"Convert" the secret key to a AES secret key
+ SecretKey aes = new SecretKeySpec(pbkdf.getEncoded(), getAlgorithm());
+
+ //Init the cipher instance
+ cipher.init(Cipher.ENCRYPT_MODE, aes);
}
@Override
- public void write(int b) throws IOException {
- //TODO
- super.write(b);
+ public void write(int decryptedInt) throws IOException {
+ byte[] decryptedByte = new byte[1];
+ decryptedByte[0] = (byte)decryptedInt;
+ byte[] encryptedByte = cipher.update(decryptedByte);
+ int encryptedInt = encryptedByte[0];
+ super.write(encryptedInt);
}
}