Java – How to encrypt AES keys using RSA without running into “javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes”

aesencryptionjavarsasockets

I have to build a simple authorization server for a project. The server has to distribute AES keys to allow its clients to communicate with each other.

When encrypting the AES key using RSA, I run into this error: "javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes".
Which is weird, since the lenght of my AES key is 128 bits = 16 bytes.

Here is the code generating the error:

private void createAndSendAES() throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, IOException, InvalidKeyException, BadPaddingException {
    KeyGenerator keyGen = KeyGenerator.getInstance("AES");
    keyGen.init(128);
    this.AESBlackboardKey = keyGen.generateKey(); // My AES key

     byte[] raw = AESBlackboardKey.getEncoded();
     System.out.println(raw.length); // Prints 16

    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, this.clientPubKey);


    SealedObject encryptedAESBlackboardKey = new SealedObject(this.AESBlackboardKey, cipher); // ERROR HERE

    ObjectOutputStream outO = new ObjectOutputStream(this.clientSocket.getOutputStream());
    outO.writeObject(encryptedAESBlackboardKey); //Transmitting the key over socket link
    outO.flush();

    System.out.println("AS: Blackboard AES key sent.");

}

Does someone know how the encryption of a 16 bytes long AES key makes me run into this kind of error and how to avoid it ?

Thanks in advance !

Best Answer

The reason why you are getting the error is that the whole object is saved, not just the 16 bytes that make up the key. So you will e.g. have the full class name in there, the serial number of the class etcetera.

If you want to keep using SealedObject then I would suggest encryption with a new random AES key and "AES/CBC/PKCS5Padding". You can then encrypt that key using the RSA algorithm (be sure to specify it fully, e.g. "RSA/NONE/OAEPPadding" or "RSA/NONE/PKCS1Padding") simply by using Cipher.doFinal().

You can also directly encrypt the generated data that way.

Another method is to simply increase the RSA key size; the RSA key size of 1024 is increasingly under threat, try to use a key size of 2048 at the bare minimum (allowing 256 - 11 = 245 bytes of storage).

Note that you can retrieve the 16 bytes from a previously created AES key by using key.getEncoded().

Related Topic