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:
- generate a symmetric key
- Encrypt the data with the symmetric key
- Encrypt the symmetric key with rsa
- send the encrypted key and the data
- Decrypt the encrypted symmetric key with rsa
- decrypt the data with the symmetric key
- 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:
Generate random AES key
byte[] keyData = new byte[32];
SecureRandom random = new SecureRandom();
random.nextBytes(keyData);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);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);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,
- Generate a secret key,
K
using an algorithm such as AES. - Encrypt the plaintext,
m
, with the newly generated secret key to get cipher text, say EK(m). - Encrypt the secret key a RSA public key, ERSA(K).
- Sent the client the cipher text, EK(m), and the encrypted key ERSA(K).
- The client can decrypt ERSA(K) with the RSA private key to get
K
. - The client then decrypt the cipher text, EK(m) with
K
to getm
.
Related Topics
Java: Getting a Substring from a String Starting After a Particular Character
How to Store Original Date/Time Without Timezone Calculation to Mongodb
Java.Sql.Sqlexception: Field Doesn't Have a Default Value
Java to Jackson Json Serialization: Money Fields
Placing a Jlabel At a Specific X,Y Coordinate on a Jpanel
Avoid Keycloak Default Login Page and Use Project Login Page
Check If Two Objects Are Equal Excluding a Few Properties
Dynamic Placeholder Substitution in Properties in Java
Reading Only the Integers from a Txt File and Adding the Value Up for Each Found
How to Parse a Json Input Stream
How to Upload a Document to Sharepoint With Java
Where Does Gradle Save Dependencies' Jars
How to Count Method Calls by Instance
Setting Default Values to Null Fields When Mapping With Jackson
Status Expected:<200> But Was:<404> in Spring Test
How to Update a Jsf Component from a Jsf Backing Bean Method