issam ahwach
issam ahwach

Reputation: 23

Given final block not properly padded exception

I have Server-Client sockets to send byte-array from client to server, I am trying to use Cipher Input Stream, Cipher output Stream but I am getting the following exception:

javax.crypto.BadPaddingException: Given final block not properly padded. Exception in thread "main" java.io.IOException: javax.crypto.BadPaddingException: Given final block not properly padded at javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:121) at javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:121) at javax.crypto.CipherInputStream.read(CipherInputStream.java:239) at javax.crypto.CipherInputStream.read(CipherInputStream.java:215) at SecretSocketServer.main(SecretSocketServer.java:46) Caused by: javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966) at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824) at com.sun.crypto.provider.DESCipher.engineDoFinal(DESCipher.java:314) at javax.crypto.Cipher.doFinal(Cipher.java:2048) at javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:118)

I tried different algorithm than "DES" but still getting the same exception this is my code:

public class SecretSocket {
    Cipher inCipher, outCipher;
    Socket socket;
    Key key;

    public SecretSocket(Socket socket, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        this.key = key;
        this.socket = socket;
        initializeCipher();
    }

    private void initializeCipher() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        outCipher = Cipher.getInstance("DES");
        outCipher.init(Cipher.ENCRYPT_MODE, key);
        inCipher = Cipher.getInstance("DES");
        inCipher.init(Cipher.DECRYPT_MODE, key);

    }

    public InputStream getInputStream() throws IOException {
        InputStream is = socket.getInputStream();
        CipherInputStream cis = new CipherInputStream(is, inCipher);
        return cis;
    }

    public OutputStream getOutputStream() throws IOException {
        OutputStream os = socket.getOutputStream();
        CipherOutputStream cos = new CipherOutputStream(os, outCipher);
        return cos;
    }
}
public class KeyGen {
    public static void writeKey() throws NoSuchAlgorithmException, FileNotFoundException, IOException {
        KeyGenerator kg = KeyGenerator.getInstance("DES");
        Key key = kg.generateKey();
        File file = new File("key1.txt");
        FileOutputStream fos = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(key);
    }
public class SecretSocketServer {
    public static void main(String[] args) throws IOException, FileNotFoundException, ClassNotFoundException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        int port = 12345;
        ServerSocket Serversocket;
        Socket clientSocket;
        Serversocket = new ServerSocket(port);
        System.out.println("Waiting for client to connect");
        clientSocket = Serversocket.accept();
        System.out.println("New Client Connected");
        Key key = KeyGen.getSecretKey();
        System.out.println("The Key is: " + key);

        SecretSocket s = new SecretSocket(clientSocket, key);
        InputStream in = s.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] b = new byte[1024];
        int numberOfBytedRead;

        while ((numberOfBytedRead = in.read(b)) >= 0) {
            baos.write(b, 0, numberOfBytedRead);
        }

        System.out.println(new String(baos.toByteArray()));
        Serversocket.close();
    }
}

public static final String KEY_FILE = "key1.txt";
public static Key getSecretKey() throws FileNotFoundException, IOException, ClassNotFoundException {
    FileInputStream fis = new FileInputStream(KEY_FILE);
    ObjectInputStream ois = new ObjectInputStream(fis);
    Key key = (Key) ois.readObject();
    return key;
}
public class SecretSocketClient {
    public static void main(String[] args) throws IOException, NoSuchAlgorithmException, ClassNotFoundException, NoSuchPaddingException, InvalidKeyException {
        int port = 12345;
        Socket soc = new Socket("localhost", port);
        System.out.println("Connected to server");
        KeyGen.writeKey();
        Key key = KeyGen.getSecretKey();
        System.out.println("Key Generated: " + key);
        SecretSocket s = new SecretSocket(soc, key);
        //InputStream in = s.getInputStream();
        OutputStream out = s.getOutputStream();
        out.write("HELLOWORLD".getBytes());
        out.flush();
        out.close();
        soc.close();
        System.out.println("The MSG has been sent");
    }
}

Upvotes: 2

Views: 15569

Answers (1)

rossum
rossum

Reputation: 15685

There are many things that can cause a "Bad Padding" exception. Basically anything that causes the end of the last block not to match the expected padding will throw the error. Possible causes include: incorrect padding setting, incorrect key, corrupted cyphertext and others.

To try and diagnose the problem, set the decryption side to NoPadding. This will accept anything, and allow you to examine the output:

  • complete garbage: you probably have an error in the key or the wrong mode setting.

  • first block garbage: you may have a key error or an IV error.

  • last block garbage: likely a corrupt end to the cyphertext file.

  • a correct decryption with some strange bytes at the end: the strange bytes are the padding.

If it really is just the padding, then set the decryption function to expect that sort of padding. Otherwise check that the key/IV/cyphertext are byte-for-byte the same for both encryption and decryption.

It is vital that you set a padding mode after diagnosis. NoPadding is insecure.

Upvotes: 2

Related Questions