I am attempting to encrypt and string and then decrypt it. I have the encryption part working, but when I try to decrypt it gives me an InvalidKeyException and says that it is missing parameters.

Here is the code

import javax.crypto.*;

import java.security.*;


public class Cryption {

    private Cipher c;
    private Key k;
    public Cryption(){
        try {
            c = Cipher.getInstance("DES/CBC/PKCS5Padding");
            KeyGenerator kg = KeyGenerator.getInstance("DES");
            k = kg.generateKey();
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public String encrypt(String dec){
        try {
            c.init(Cipher.ENCRYPT_MODE, k);
            String enc = new String(c.doFinal(dec.getBytes()));
            return enc;
        } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
        return null;
    }

    public String decrypt(String enc){
        try {
            c.init(Cipher.DECRYPT_MODE, k);
            String dec = new String(c.doFinal(enc.getBytes()));
            return dec;
        } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

and here is the output that I get when I run the program passing in the string Hello World

Hello World
oØÁÖG  _|bÁW3° 
java.security.InvalidKeyException: Parameters missing
    at com.sun.crypto.provider.CipherCore.init(CipherCore.java:388)
    at com.sun.crypto.provider.DESCipher.engineInit(DESCipher.java:186)
    at javax.crypto.Cipher.init(Cipher.java:1210)
    at javax.crypto.Cipher.init(Cipher.java:1153)
    at Cryption.decrypt(Cryption.java:35)
    at Main.main(Main.java:12)
null

The main method mentioned is just a test class

why do you return null from those methods? I think it would be better to throw an Exception from the catch block, or have your method throw the exception instead of handling with it.

the main method is just a test class ... yeah well, since we don't know what code is in that 'test class', we can't really say much about it, can we?

Here is the main class. Like I said it is a very simple test class

public class Main {

    public static void main(String[] args) {
        Cryption c = new Cryption();

        String text = "Hello World";
        System.out.println(text);
        String encText = c.encrypt(text);
        System.out.println(encText);
        String decText = c.decrypt(encText);
        System.out.println(decText);
    }

}

After throwing the exceptions this is what my code looks like

import javax.crypto.*;

import java.security.*;


public class Cryption {

    private Cipher c;
    private Key k;
    public Cryption(){
        try {
            c = Cipher.getInstance("DES/CBC/PKCS5Padding");
            KeyGenerator kg = KeyGenerator.getInstance("DES");
            k = kg.generateKey();
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public String encrypt(String dec) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
            c.init(Cipher.ENCRYPT_MODE, k);
            String enc = new String(c.doFinal(dec.getBytes()));
            return enc;

    }

    public String decrypt(String enc) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
            c.init(Cipher.DECRYPT_MODE, k);
            String dec = new String(c.doFinal(enc.getBytes()));
            return dec;
    }
}

Thanks for the help.

Edited 3 Years Ago by sirlink99

don't forget to catch those exceptions in your main method.

puzzled a bit with your code, and added an IvParameterSpec with which I got it to work:

here I hardcoded the value, of course it's better to have one generated, so that each encryption has it's own key.

public String encrypt(String dec) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
c.init(Cipher.ENCRYPT_MODE, k, ivspec);
String enc = new String(c.doFinal(dec.getBytes()));
return enc;
}

public String decrypt(String enc) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
System.out.println("k = " + k);
c.init(Cipher.DECRYPT_MODE, k, ivspec);
String dec = new String(c.doFinal(enc.getBytes()));
return dec;
}
This question has already been answered. Start a new discussion instead.