1

I have an AES 128-bit encryption method which encrypts messages. But it does not encrypt messages which are longer than 45 characters. Therefore, i was thinking if i can do that by splitting messages with longer than 45 chars into an array of size 45 chars or array list, then i encrypt each block at a time.

So, if i have a message of long 90, i should to have two arrays of size 45 each (or array of size two and each of size 45chars). or an arraylist to do that. if i have a message of long 180 then i should have a block of 4 arrays.

UPDATE: So my initial issue was in not being able to send long messages using AES encryption in a client-server chat.

The following are the codes of AES implementation but without any padding or IV in it.

First i have a client; who sends messages encrypted using AESmsgEncryption class below.

Client class

    public void send(String sendMessage) {

        userName = GUI.getUserName();

        //each index of the array will contain a substring of the send message (maximum length 45 char)
        if (sendMessage.length() > 45) {
//      String [] arrayOfStrings = new String[sendMessage.length()/45];
        int sizeOfArray = sendMessage.length()/45;
        System.out.println("CANT SEND MESSAGES LONGER THAN 45");

        } else {    

            String ciphertext  = msgAESEnDe.encryptAES(sendMessage, scrtkey);
            System.out.println(userName + ": " + ciphertext + "  <-- encrypted before sending");
            out.println(userName + "#ciphertext$" + ciphertext);
            out.flush();

        }
}

Once the client sends out a message, the receiver then receives it at it is(encrypted) and sends it back to the online clients. Once the online clients receives the encrypted text message they decrypt the message using the following code In another receive method in the client class

String username = recMessage.substring(0, recMessage.indexOf(' '));
                String ciphertxtWithNoName = recMessage.substring(recMessage.indexOf(':') + 2);

                scrtkey = new SecretKeySpec(secrtKeyByte, "AES");

                String plaintext = msgAESEnDe.decryptedPlain(ciphertxtWithNoName, scrtkey);
                System.out.println(username +" " + plaintext +"  <-- after decryption");

                //current time
                String time = log.format(new Date());

                // Displaying received message.
                ClientGUI.TA_CONVERSATION.append(time+ " ["+username.substring(0, username.length()-1) + "]: " + plaintext + "\n");

So in AESmsgEncryption class i have a method as follows;

public final String encryptAES(final String plaintext, SecretKey key) {
        String ciphertext = new String();

        try {
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] bytePlaintext = plaintext.getBytes();
            byte[] byteCiphertext = cipher.doFinal(bytePlaintext);
            ciphertext = new BASE64Encoder().encode(byteCiphertext);

        } catch (NoSuchAlgorithmException e) {
            System.out.println("NoSuchAlgorithmException: " + e);
        } catch (NoSuchPaddingException e) {
            System.out.println("NoSuchPaddingException: " + e);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
            System.out.println("InvalidKeyException: " + e);
        } catch (IllegalBlockSizeException e) {
            System.out.println("IllegalBlockSizeException: " + e);
        } catch (BadPaddingException e) {
            System.out.println("BadPaddingException: " + e);
        }
        return ciphertext;
    }

public final String decryptedPlain(String ciphertext, SecretKey key) {
        try {
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, key);


            byte [] decodedValue = new Base64().decode(ciphertext.getBytes());
            plaintext = cipher.doFinal(decodedValue);

        } catch (NoSuchAlgorithmException e) {
            System.out.println("NoSuchAlgorithmException: " + e);
        } catch (NoSuchPaddingException e) {
            System.out.println("NoSuchPaddingException: " + e);
        } catch (InvalidKeyException e) {
            System.out.println("InvalidKeyException: " + e);
        } catch (IllegalBlockSizeException e) {
            System.out.println("IllegalBlockSizeException: " + e);
        } catch (BadPaddingException e) {
            System.out.println("BadPaddingException: " + e);
        }

        return new String(plaintext);
    }

The AES secret key is generated in the server side and sent encrypted using RSA, and then sent to each client, that is why in the client i have to give the scrtkey in the calling to the encryptAES and decryptedPlain methods.

To re state my problem; the above code cannot send messages longer than 45 chars, how can i make it send messages longer than 45 chars? If i needed to use padding and IV, the server should send the IV along with the secret key, right?

I hope the above description is clear.

How can i do that in JAVA?

Thanks

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
Deyaa
  • 123
  • 1
  • 2
  • 11

2 Answers2

1

These kind of padding that you are getting is normally not related to any limitation of the cipher. It's because:

  1. you loose data during communication;
  2. you loose data during encoding/decoding.

The last one is most likely, and if you use a random IV or key, it's likely that it happens randomly. In that case splitting the string may only temporarily hide the issue instead of solving it.

If the ciphertext is handled as string data you should use base 64 encoding. Make sure that the full ciphertext in bytes is the same after the encrypt method and before the decrypt method by viewing it as hexadecimal string.

AES can easily encrypt gigabytes of information (although the security depends on the use case and mode of operation). Splitting the plaintext should not be necessary.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • I have fixed the issue, which was caused because the ciphertext was long so ciphertext will eventually go into a new line. So i just removed new lines, and then it worked. Later i have implemented CBC and IV. Thank you for the clarification. – Deyaa Jan 16 '15 at 21:40
0

I think you could something like this:

int length=input.length();
for(int i=0; i<length; i+=45) {
    encrypt(input.substring(i, i+45<=length ? i+45 : length ));
}

A bit of explanation about i+45<=length ? i+45 : length

The format is expression ? if yes : if no

It checks if i+45 <= length
When true: Substring from i to i+45
When false: Substring from i to the end (length)

If you wouldn't do this check you will get an error of type StringIndexOutOfBoundsException. (Unless your input is exactly 45, 90, 135 etc bytes long)

More info: here

Community
  • 1
  • 1
Charlie
  • 978
  • 1
  • 7
  • 27