2

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");
    }
}
issam ahwach
  • 23
  • 1
  • 1
  • 5
  • Format your code please. – Aluan Haddad Apr 11 '18 at 14:02
  • Possible duplicate of https://stackoverflow.com/questions/8049872/given-final-block-not-properly-padded – Ahmed Ashour Apr 11 '18 at 14:13
  • 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. – Trinopoty Apr 11 '18 at 14:15
  • i tried to use it, but i'am still getting the same exception. – issam ahwach Apr 11 '18 at 14:44
  • 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. – Trinopoty Apr 11 '18 at 14:52
  • 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. – issam ahwach Apr 11 '18 at 14:57
  • @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 Apr 12 '18 at 23:01

1 Answers1

2

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.

rossum
  • 15,344
  • 1
  • 24
  • 38
  • 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. – dave_thompson_085 Apr 12 '18 at 22:55