Rsa Decryption Error - Illegalblocksizeexception: Data Must Not Be Longer Than 128 Bytes

RSA decryption error - IllegalBlockSizeException: Data must not be longer than 128 bytes

Your signature string contains 256 characters, however this is hexadecimal and really represents 128 bytes.

Before you verify the signature, you must convert it back to a byte array. This is not achieved through someString.getBytes() but rather via DatatypeConverter.parseHexBinary(someString) (or any other method you prefer from Google).

Also, I would strongly recommend you use the Signature class rather than the Cipher class when signing messages. Currently your code can only handle messages that are smaller than 128 bytes in length (smaller, in fact, due to padding). Instead, you should be hashing the message prior to signing (e.g. using the SHA256withRSA mechanism).

getting a IllegalBlockSizeException: Data must not be longer than 256 bytes when using rsa

The RSA algorithm can only encrypt data that has a maximum byte length
of the RSA key length in bits divided with eight minus eleven padding
bytes, i.e. number of maximum bytes = key length in bits / 8 - 11.

So basicly you divide the key length with 8 -11(if you have padding). For example if you have a 2048bit key you can encrypt 2048/8 = 256 bytes (- 11 bytes if you have padding). So, either use a larger key or you encrypt the data with a symmetric key, and encrypt that key with rsa (which is the recommended approach).

That will require you to:

  1. generate a symmetric key
  2. Encrypt the data with the symmetric key
  3. Encrypt the symmetric key with rsa
  4. send the encrypted key and the data
  5. Decrypt the encrypted symmetric key with rsa
  6. decrypt the data with the symmetric key
  7. done :)

Java RSA decryption javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes

As Topaco mentioned (all credits to him) when decrypting, the ciphertext must be Base64 decoded and not UTF8 encoded:

In my case, it was UTF8 encoded.

``` Base64.getDecoder().decode("OixtTJRXe2nDRWDBqSs9m4wN[...]17/MKpw==") `` worked.

how to solve javax.crypto. IllegalBlockSizeException without increase the size if key

With asymmetric encryption there is no way to encrypt data longer than key minus padding. Since it's 11 bytes for you I can conclude you use PKCS#1 padding. What you can do is try to compress data, but depending on data length and nature it easily can fail. Another option is to combine symmetric block ciphers (which has no limitation for the size of data) and asymmetric encryption:

  1. Generate random AES key

    byte[] keyData = new byte[32];
    SecureRandom random = new SecureRandom();
    random.nextBytes(keyData);
  2. Encrypt data with AES.

    // zero filled input vector
    byte[] ivData = new byte[32];
    IvParameterSpec iv = new IvParameterSpec(ivData);
    SecretKeySpec keySpec = new SecretKeySpec(keyData, "AES");
    Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
    aes.init(Cipher.ENCRYPT_MODE, keySpec, iv);
    byte[] cipherText = aes.doFinal(data);
  3. Encrypt AES key (for AES-256 it's 32 bytes) with RSA private key.

    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.WRAP_MODE, rsaKeyPair.getPublic());
    byte[] wrappedKey = cipher.doFinal(keyData);
  4. Combine wrappedKey with cipherText. Can be done with just appending one to another, but also some binary format can be used.

Large data not encrypted with RSA Encryption

Here is a direct quote from the seminal book titled Cryptography Engineering by Ferguson, Schneier, and Kohno,

Encrypting a message is the canonical application of RSA, yet it is almost never used in practice. The reason is simple: the size of the message that can be encrypted using RSA is limited by the size of n. In real systems, you cannot even use all the bits, because the encoding function has an overhead. This limited message size is too impractical for most applications, and because the RSA operation is quite expensive in computational terms, you don’t want to split a message into smaller blocks and encrypt each of them with a separate RSA operation.

In other words, for a n-bit RSA key, the maximum length of data RSA can encrypt in bytes is

Floor(n/8) - 11 

where 11 bytes is for padding

So for a key size of 512 bits, the maximum length of data that can be encrypted is,

512/8 - 11 = 53 bytes

Again from the book Cryptography Engineering,

The solution used almost everywhere is to choose a random secret key K, and encrypt K with the RSA keys. The actual message m is then encrypted with key K using a block cipher or stream cipher. So instead of sending something like ERSA(m), you send ERSA(K),EK(m).

Basically, it's telling you do the following to get over the limitation of RSA,

  1. Generate a secret key, K using an algorithm such as AES.
  2. Encrypt the plaintext, m, with the newly generated secret key to get cipher text, say EK(m).
  3. Encrypt the secret key a RSA public key, ERSA(K).
  4. Sent the client the cipher text, EK(m), and the encrypted key ERSA(K).
  5. The client can decrypt ERSA(K) with the RSA private key to get K.
  6. The client then decrypt the cipher text, EK(m) with K to get m.


Related Topics



Leave a reply



Submit