Reputation: 1035
I am running into this problem when trying to decrypt a message.
An exception or error caused a run to abort: Data must not be longer than 256 bytes
javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
My code is as follows.
package com.smth.what.api
import java.security.spec.X509EncodedKeySpec
import java.security.{KeyFactory, PrivateKey, PublicKey}
import javax.crypto.Cipher
import org.apache.commons.codec.binary.Base64
object Encryptor {
private val publicKeyString: String = System.getenv("PUB_KEY")
private val privateKeyString: String = System.getenv("PRIV_KEY")
private val publicKey = readPemPublicKey(publicKeyString)
private val privateKey = readPemPrivateKey(privateKeyString)
private def readPemPublicKey(publicKey: String): PublicKey = {
val pemPublicKey = publicKey.replace("\n", "")
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replace(" ", "")
val publicKeyBytes: Array[Byte] = Base64.decodeBase64(pemPublicKey)
val publicKeySpec = new X509EncodedKeySpec(publicKeyBytes)
val keyFactory = KeyFactory.getInstance("RSA")
keyFactory.generatePublic(publicKeySpec)
}
private def readPemPrivateKey (privateKey: String): PrivateKey = {
val pemPrivateKey = privateKey.replace("\n", "")
.replace("-----BEGIN RSA PRIVATE KEY-----", "")
.replace("-----END RSA PRIVATE KEY-----", "")
.replace(" ", "")
val privateKeyBytes: Array[Byte] = Base64.decodeBase64(pemPrivateKey)
val keyFactory = KeyFactory.getInstance("RSA")
import java.security.spec.RSAPrivateCrtKeySpec
import sun.security.util.DerInputStream
val derReader = new DerInputStream(privateKeyBytes)
val seq = derReader.getSequence(0)
val modulus = seq(1).getBigInteger
val publicExp = seq(2).getBigInteger
val privateExp = seq(3).getBigInteger
val prime1 = seq(4).getBigInteger
val prime2 = seq(5).getBigInteger
val exp1 = seq(6).getBigInteger
val exp2 = seq(7).getBigInteger
val crtCoef = seq(8).getBigInteger
val keySpec = new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef)
keyFactory.generatePrivate(keySpec)
}
def encrypt(inputString: String, key: PublicKey = publicKey): String = {
val cipher: Cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.ENCRYPT_MODE, key)
new String(cipher.doFinal(inputString.getBytes("UTF-8")))
}
def decrypt(inputString: String, key: PrivateKey = privateKey): String = {
val cipher: Cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.DECRYPT_MODE, key)
val inputStringBytes = inputString.getBytes("UTF-8")
new String(cipher.doFinal(inputStringBytes))
}
}
My key's size is 2048
. It was generated via openssl genrsa
with .pem
output.
I use IntelliJ's environment variable to provide both public and private keys (via the Edit Configurations, copying and pasting them).
The error came from this line
new String(cipher.doFinal(inputStringBytes))
from decrypt
function.
I have been reading a few stackoverflow's posts (such as this one), however, I still do not understand what is going on.
If possible, I would like a very basic explanation, as encryption/ decryption is a new area for me.
Upvotes: 0
Views: 962
Reputation: 1035
After attempting different things, what works is to apply Base64
encoding to the encrypted message and then use Base64
decoding when decrypting the encrypted message. This is aligned with what @James K Polk comment is saying.
See the updated code (only for the functions encrypt
and decrypt
as the rest remains the same)
def encrypt(inputString: String, key: PublicKey = publicKey): String = {
cipher.init(Cipher.ENCRYPT_MODE, key)
val encrypted: Array[Byte] = cipher.doFinal(inputString.getBytes())
Base64.encodeBase64String(encrypted)
}
def decrypt(inputString: String, key: PrivateKey = privateKey): String = {
cipher.init(Cipher.DECRYPT_MODE, key)
val decodedInputString: Array[Byte] = Base64.decodeBase64(inputString)
val decrypted: Array[Byte] = cipher.doFinal(decodedInputString)
new String(decrypted)
}
Upvotes: 1