0
votes

I am trying to decrypt a message on server - the error what I got is

Encryption technique used - DES.

--Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded

I am having a very difficult time trying to solve this problem, any help will be appreciated

class TCPClient {
public static void main(String argv[]) throws Exception {
    byte[] sentence, textEncrypted;
    String modifiedSentence;
    String password;
    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
    Socket clientSocket = new Socket("localhost", 6789);
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
    password = "Passcode";
    byte[] salt = new byte[64];
    Random rnd = new Random();
    rnd.nextBytes(salt);
    byte[] data = deriveKey(password, salt, 64);

    // BufferedReader inFromServer = new BufferedReader(new
    // InputStreamReader(clientSocket.getInputStream()));
    System.out.println("Enter the Data to be transmisted to server\n");
    sentence = inFromUser.readLine().getBytes();
    SecretKey desKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(data));
    Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, desKey);
    textEncrypted = cipher.doFinal(sentence);
    outToServer.writeBytes(new String(textEncrypted) + '\n');
    clientSocket.close();
}

public static byte[] deriveKey(String password, byte[] salt, int keyLen) {
    SecretKeyFactory kf = null;
    try {
        kf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    KeySpec specs = new PBEKeySpec(password.toCharArray(), salt, 1024, keyLen);
    SecretKey key = null;
    try {
        key = kf.generateSecret(specs);
    } catch (InvalidKeySpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return key.getEncoded();
}
}

Server side code

class TCPServer {
public static void main(String argv[]) throws Exception {
    String password = null;
    String capitalizedSentence;
    ServerSocket welcomeSocket = new ServerSocket(6789);

    while (true) {
        Socket connectionSocket = welcomeSocket.accept();
        BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
        password = "Passcode";
        byte[] salt = new byte[64];
        Random rnd = new Random();
        rnd.nextBytes(salt);
        byte[] data = deriveKey(password, salt, 64);
        byte [] EncyptedText = inFromClient.readLine().getBytes();
        System.out.println("Received Encrypted message " + EncyptedText);
        SecretKey desKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(data));
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, desKey);
        // Decrypt the text
        System.out.println("Text Received " + EncyptedText);
        byte[] textDecrypted = cipher.doFinal(EncyptedText);
        System.out.println("Text Decryted : " + new String(textDecrypted));

    }
}

public static byte[] deriveKey(String password, byte[] salt, int keyLen) {
        SecretKeyFactory kf = null;
        try {
            kf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        KeySpec specs = new PBEKeySpec(password.toCharArray(), salt, 1024, keyLen);
        SecretKey key = null;
        try {
            key = kf.generateSecret(specs);
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return key.getEncoded();
}
}
1
Just brainstorming here but your client side salt is different from the server side one. Won't that cause any problem?Andrei-Marius Longhin
I did tried using salt but I end up with same error :(Vaibhav Mishra

1 Answers

0
votes

You will lose data doing this:

outToServer.writeBytes(new String(textEncrypted) + '\n');

besides that, it's not necessary. Ciphertext is not really text for modern ciphers, it's binary. And as sockets provide binary InputStreams and OutputStreams there is simply no reason to convert the ciphertext to strings either. All that is required is to convert possible input strings to binary (using the same encoding on both the client and server, of course - UTF-8 is preferred nowadays).