'AES Encryption and Decryption not getting decrypted word in print statements but shows up in debugger

Hi I'm working on a socket programming project where it is a encrypted client and server. I have all the code working to create public keys, private keys, aes secret encryption and decryption. The issue is when I sent my encrypted values over to the server, it is missing the first few values of the encrypted values. But when I run it through the debugger and add breakpoints it prints the right decrypted value.

For this say my text is "jesus" this is my client class for example.

Client.java

        try {
            IvParameterSpec iv = new IvParameterSpec(initVector);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE,  key, iv);

            byte[] encrypted = cipher.doFinal(value.getBytes(StandardCharsets.UTF_8));
            System.out.println("encrypted string: "
                    + Base64.getEncoder().encodeToString(encrypted));

            return Base64.getEncoder().encodeToString(encrypted);

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

        return null;
    }


public static void main(Strings[] args) {
// I have all the code for making keys and creating the Socket connection ( all of this stuff works) 

 System.out.println("What is your port number");
        port = scanner.nextInt();
        System.out.println("What is your ip address");
        ipAddress = scanner.next();
        System.out.println("What is your client's private key file");
        privateKeyFile = scanner.next();
        System.out.println("What is your server's public key file");
        publicKeyFile = scanner.next();

        System.out.println("What is your text string");
        textString = scanner.next();

        Socket socket = new Socket(ipAddress, port);
        DataInputStream  input = new DataInputStream(socket.getInputStream());
        // sends output to the socket
        DataOutputStream  output = new DataOutputStream(socket.getOutputStream());
 PrivateKey clientPrivateKey = loadPrivateKey(privateKeyFile, "RSA");
        PublicKey  serverPublicKey = loadPublicKey(publicKeyFile, "RSA");

   // I have more but essentially that is part of it 


// stuff that isn't working 
    SecureRandom sr = new SecureRandom();
        KeyGenerator kg= KeyGenerator.getInstance("AES");
        kg.init(256, sr);
        SecretKey key256AES = kg.generateKey();

 String encodedTextString =  new String(Base64.getEncoder().encode(
                textString.getBytes(StandardCharsets.UTF_8)));
 Integer textStringLengthFromBytes = textByte.length;

     byte[] textSignature = signDigitalSignature(textByte, clientPrivateKey, "SHA512withRSA");

  byte[] IV = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 String cipherText = encrypt(key256AES, IV, textString);
        System.out.println("Cipher" + cipherText);

    output.write(textStringLengthFromBytes);

        output.write(textSignature);

        output.write(cipherText.getBytes(StandardCharsets.UTF_8));

} 




Server.java

 public static String decrypt(SecretKey key, byte[]  initVector, String encrypted) {
        try {
            IvParameterSpec iv = new IvParameterSpec(initVector);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, key, iv);

            byte[] plainText = cipher.doFinal(Base64.getDecoder()
                    .decode(encrypted));

            return new String(plainText);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }
  public static void main(String args[]){

          // round 2 for this project I have to get the size of the plaintext string and //the aesEncryptedString and the actual cipher text
                Integer size = in.readInt();
                System.out.println("size" + size);


               byte[] textSignatureFromClient = new byte[256];
               in.readFully(textSignatureFromClient);

               System.out.println("textSignatureFromClient" + 
               Arrays.toString(textSignatureFromClient));

// having issues with this part below
                String cipherText = in.readLine();

                System.out.println("Cipher " + cipherText);


            byte[] IV = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                String decryptedVal = decrypt(AESSecretKey, IV, cipherText);
                System.out.println("Text" + decryptedVal);

}


Here is an output of what values are stored in the ciphers: Client ciphertext says: V5VoP7K/Bzzj5291kd3WYg== Server ciphertext says: oP7K/Bzzj5291kd3WYg==

Here is the error I get as well: java.lang.IllegalArgumentException: Input byte array has incorrect ending byte at 20

But when I debug, I pass over the decrypt line in the the server and it gets me the word jesus in plaintext both in the debugger variables and in the console. Also I apologize for how messy my code is. I'm going to clean it and modularize it more once all my requirements are met.



Solution 1:[1]

I have absolutely no idea why this worked but I this is what my Server.java looks like now. I just added "" at the end of in.readline() because I noticed when I added comments it got the full cipher. Additionally, it is receiving the text signature before the cipher with no issues.

Server.java



 byte[] textSignatureFromClient = new byte[256];
            in.readFully(textSignatureFromClient);


            String cipherText = in.readLine() + "";
             try {
                    byte[] IV = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
                    String decryptedVal = decrypt(AESSecretKey, IV, cipherText.trim());
                    System.out.println("Decrypted Text: " + decryptedVal);
                }
                catch(Exception e){
                    System.out.println("Decryption error" + e);
                } 

Client.java


 String encodedTextString =  new String(Base64.getEncoder().encode(
                textString.getBytes(StandardCharsets.UTF_8)));
        byte[] textByte =  encodedTextString.getBytes();
        byte[] textSignature = signDigitalSignature(textByte, clientPrivateKey, "SHA512withRSA");
        output.write(textSignature);
        output.flush();
        
        String cipherText = encrypt(key256AES, IV, textString);
        System.out.println("Cipher" + cipherText);
        output.write(cipherText.getBytes(StandardCharsets.UTF_8));
        output.flush(); ```

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Swechha Ghimire