John Doe
John Doe

Reputation: 1

Encrypting and Decrypting final block not properly padded error?

I'm trying to fix my code. In my code, I'm trying to generate a 16bit key which I've already done. Secondly, generate a random message which is also done. Encrypt and decrypt the data which I'm getting errors on. Lastly have a brute force algorithm to decrypt the message which i'll try doing later. So for my encryption the code encrypts it but doesn't encrypt the random generated string. I'm getting bunch of errors.

Errors: 
Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
    at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:991)
    at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847)
    at java.base/com.sun.crypto.provider.BlowfishCipher.engineDoFinal(BlowfishCipher.java:319)
    at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2189)
    at Assignment1Demo.decryption(Assignment1Demo.java:109)
    at Assignment1Demo.bruteForce(Assignment1Demo.java:130)
    at Assignment1Demo.main(Assignment1Demo.java:30)

Exception in thread "main" java.lang.NullPointerException
    at Assignment1Demo.bruteForce(Assignment1Demo.java:131)
    at Assignment1Demo.main(Assignment1Demo.java:30)

My code:

import java.util.Random;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class Assignment1Demo {

    private static String msg;  
    private static String msgE; 
    private static String msgD;
    private static int key;

    public static void main(String[] args){
        //TODO: You can only call methods in main method            

        key = generateKey();

        msg = generateMsg();

        msgE = encryption(key,msg);

        bruteForce(msgE);
    }

    private static int generateKey() {

        //TODO: implement step a (randomly generate 16-bit key)

        //16 bit digit means 2^16 -1 in decimal     
        Random rand = new Random(); 
        return rand.nextInt((int) (Math.pow(2, 16)-1));
    }

    private static String generateMsg() {

        //TODO: implement step b (randonly generate a string with an even number of characters)
        String chractersU="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String chractersL=chractersU.toLowerCase();
        String space=" ";
        String alphanum=chractersU+space+chractersL;
        String random="";
        int length=alphanum.length();
        Random rand=new Random();
        char[] text=new char[length];

        for(int i=0;i<length;i++) {
            text[i]=alphanum.charAt(rand.nextInt(alphanum.length()));
        }

        for(int i=0;i<text.length/2;i++) {
            if(text.length%2!=0) {
                random += text[i];
            }
        }

        return random;
    }

    private static String encryption (int key, String msg) {

        //TODO: implement step c (encrypt the message)

        String strData="";
        String strKey=Integer.toString(key);

        try {
            SecretKeySpec skeyspec=new SecretKeySpec(strKey.getBytes(),"Blowfish");
            Cipher cipher=Cipher.getInstance("Blowfish");
            cipher.init(Cipher.ENCRYPT_MODE, skeyspec);
            byte[] encrypted=cipher.doFinal(msg.getBytes());
            strData=new String(encrypted);

        } catch (Exception e) {
            e.printStackTrace();

        }
        return strData;
    }   

    private static void decryption(int key, String msgE) {

        //TODO: implement step d (decryption)

        String strKey = Integer.toString(key);
        String strData="";
        try {
            SecretKeySpec skeyspec=new SecretKeySpec(strKey.getBytes(),"Blowfish");
            Cipher cipher=Cipher.getInstance("Blowfish");
            cipher.init(Cipher.DECRYPT_MODE, skeyspec);
            byte[] decrypted=cipher.doFinal(msgE.getBytes());
            strData=new String(decrypted);

        } catch (Exception e) {
            e.printStackTrace();    
        }
        System.out.println(strData);
    }

    private static void bruteForce(String msgE) {

        //TODO: implement bruteForce algorithm, you may need the above decryption(key,msgE) method

        boolean isEnglisString = msgE.matches("[a-zA-Z]+");

        if(isEnglisString)
            System.out.println("Yes encrypted message is Randomly English generated message " + msgE);
        else
            System.out.println("encrypted message is Not Randomly english generated message "+msgE);

        decryption(key, msgE);
        isEnglisString = msgD.matches("[a-zA-Z]+");

        if(isEnglisString)
            System.out.println("Yes decrypted message is Randomly english generated message "+ msgD);
        else
            System.out.println("decrypted message is not Randomly english generated message "+ msgD);
    }
}

Upvotes: 0

Views: 2327

Answers (1)

martijno
martijno

Reputation: 1783

One problem is that you're doing some type conversions that I'm not sure will work. For instance in your encryption method you convert the encrypted byte array to a string (using new String(encrypted)) and then back to byte array in the decryption method (using getBytes()). The result is not the same byte array.

Why are you using String instead of byte[] for your plain- and cipher text? (Same for your key, why use int instead of byte[]?)

Upvotes: 1

Related Questions