Hello!
I have been playing around with the javax.crypto package, and testing encryption/decryption so I can implement it in my program.
After reading through
I noted that instead of fussing around with the DES Key "limit" (8 bytes), one can used "PBE" (Password Based Encryption) and supply a char array to create an encryption Key with.
However, unlike using DES encryption (which worked perfectly), PBE encryption gives me strange Exceptions which I cannot solve.
java.security.InvalidAlgorithmParameterException: Parameters missing
InvalidKeyException: requires PBE parameters
(stack traces at end, so as to include SSCCE code)
I am at a loss as to why these arise.
This is the code of my dummy program. What I've attempted to do to fix these errors follows that.
package SBX;
import java.io.*;
import java.security.*;
import java.security.spec.*;
import javax.swing.*;
import javax.crypto.*;
import javax.crypto.spec.*;
class Program {
// Instance Variables
String strToEncrypt = "This wants to be encrypted using Password Based Encryption";
String decryptedResult = null;
String algorithm = "PBEWithMD5AndDES";
String password = "ProgramPassword";
String filepath = "dummyFile.txt";
// Main
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Program().start();
}
});
}
// Constructors
public Program() {}
// Methods
public void start() {
encrypt();
decrypt();
}
public void encrypt() {
System.out.println("Encrypting: " + strToEncrypt);
try {
Cipher cipher = Cipher.getInstance(algorithm);
SecretKey key = SecretKeyFactory.getInstance(algorithm).generateSecret(new PBEKeySpec(password.toCharArray()));
cipher.init(Cipher.ENCRYPT_MODE, key);
FileOutputStream fos = new FileOutputStream(filepath);
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
ObjectOutputStream oos = new ObjectOutputStream(cos);
oos.writeObject(strToEncrypt);
oos.close();
cos.close();
fos.close();
}
catch (NoSuchAlgorithmException nsae) {
System.out.println("No Such Algorithm!");
nsae.printStackTrace();
}
catch (NoSuchPaddingException nspe) {
System.out.println("No Such Padding!");
nspe.printStackTrace();
}
catch (InvalidKeySpecException ikse) {
System.out.println("Key Spec Was Invalid!");
ikse.printStackTrace();
}
catch (InvalidKeyException ike) {
System.out.println("Invalid Key!");
ike.printStackTrace();
}
catch (IOException ioe) {
System.out.println("IO Error!");
ioe.printStackTrace();
}
}
public void decrypt() {
if (new File(filepath).exists()) {
try {
Cipher cipher = Cipher.getInstance(algorithm);
SecretKey key = SecretKeyFactory.getInstance(algorithm).generateSecret(new PBEKeySpec(password.toCharArray()));
cipher.init(Cipher.DECRYPT_MODE, key);
FileInputStream fis = new FileInputStream(filepath);
CipherInputStream cis = new CipherInputStream(fis, cipher);
ObjectInputStream ois = new ObjectInputStream(cis);
decryptedResult = (String) ois.readObject();
ois.close();
cis.close();
fis.close();
System.out.println("Decrypted: " + decryptedResult);
}
catch (NoSuchAlgorithmException nsae) {
System.out.println("No Such Algorithm!");
nsae.printStackTrace();
}
catch (NoSuchPaddingException nspe) {
System.out.println("No Such Padding!");
nspe.printStackTrace();
}
catch (InvalidKeySpecException ikse) {
System.out.println("Key Spec Was Invalid!");
ikse.printStackTrace();
}
catch (InvalidKeyException ike) {
System.out.println("Invalid Key!");
ike.printStackTrace();
}
catch (IOException ioe) {
System.out.println("IO Error!");
ioe.printStackTrace();
} catch (ClassNotFoundException cnfe) {
System.out.println("Could Not Class Cast!");
cnfe.printStackTrace();
}
}
}
}
Stack Traces
java.security.InvalidKeyException
java.security.InvalidKeyException: requires PBE parameters
at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineInit(DashoA13*..)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at SBX.Program.decrypt(Program.java:78)
at SBX.Program.start(Program.java:34)
at SBX.Program$1.run(Program.java:23)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)Invalid Key!
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
java.security.InvalidAlgorithmParameterException
at com.sun.crypto.provider.SunJCE_ab.a(DashoA13*..)
at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineInit(DashoA13*..)
... 16 more
While encryption works beautifully, the decryption method encounters the above errors. At first I thought the
java.security.InvalidKeyException was caused because, well, I was using an InvalidKey - so I tried using PBEKey in place of SecretKey, and classcasting the returned SecretKey from generateSecret into a PBEKey.
This caused classcast exceptions because somehow the compiler thought I was attempting to use the PBEKey within another package (forget the name), even though I was explicitly naming the path for the PBEKey every time it appeared in my code...
So then I thought maybe that PBE encryption doesn't work in the same way as DES encryption - ie, I can't follow the same routine with decryption as I did encryption... but that doesn't even make sense, how can I decrypt encrypted data with a Key that isn't exactly the same as the one used to encrypt it?
Any help would be appreciated!