Given final block not properly padded exception

11,503

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.

Share:
11,503

Related videos on Youtube

issam ahwach
Author by

issam ahwach

Updated on June 04, 2022

Comments

  • issam ahwach
    issam ahwach almost 2 years

    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");
        }
    }
    
    • Aluan Haddad
      Aluan Haddad about 6 years
      Format your code please.
    • Ahmed Ashour
      Ahmed Ashour about 6 years
    • Trinopoty
      Trinopoty about 6 years
      You need to use DES/ECB/PKCS5Padding instead of DES or add a padding manually. And, we don't know where exactly you're getting the exception.
    • issam ahwach
      issam ahwach about 6 years
      i tried to use it, but i'am still getting the same exception.
    • Trinopoty
      Trinopoty about 6 years
      The problem is either with wrong key or wrong padding. A wrong key can generate incorrect padding on decryption. Try to log the length of data before and after encryption on both sides.
    • issam ahwach
      issam ahwach about 6 years
      How can i use a correct key ? the Keygen class generates the key and stores it in a file, then the same key is retrieved for decryption.
    • dave_thompson_085
      dave_thompson_085 about 6 years
      @Trinopoty: JCE defaults to ECB and PKCS5Padding (which is actually PKCS7) for symmetric ciphers, so you don't need to specify them, although it is clearer and more robust to do so.
  • dave_thompson_085
    dave_thompson_085 about 6 years
    Key yes -- since it is coming from a file, make sure it's the same file. IV is not used for ECB (although another mode that does use an IV/nonce would be better) Ciphertext will be hard to check since it's 'inside' the CipherInputStream and CipherOutputStream . Padding does not improve security; in fact for unauthenticated encryption it can decrease security by providing an oracle; see POODLE for a dramatic example.