1

I have problem with decryption (or maybe wrong encryption, too) of data with RSA in Java. I wanna encrypt public key with some more info in String and then decrypt this public key and encrypt with it something (I use 2048 RSA):

Encryption:

public void saveExportToFile(String fileName, BigInteger mod, BigInteger exp, String info, PublicKey puk) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(baos));
    try {
        oout.writeObject(mod);
        oout.writeObject(exp);
        oout.writeChars(info);
        oout.close();
        baos.close();
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, puk);

        FileOutputStream fos = new FileOutputStream(new File(fileName));
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        byte[] data = baos.toByteArray();

        int i = 0;
        byte[] buffer = new byte[128];
        byte[] cipherData = null;
        while (i < data.length) {
            if (i+128 >= data.length) {
                buffer = new byte[data.length - i];
                System.arraycopy(data, i, buffer, 0, data.length - i);
                cipherData = cipher.doFinal(buffer);
                bos.write(cipherData);
            } else {
                System.arraycopy(data, i, buffer, 0, 128);
                cipherData = cipher.doFinal(buffer);
                bos.write(cipherData);
            }
            i += 128;
        }

        bos.close();
    } catch (Exception e) {
        throw new IOException("Unexpected error", e);
    }
}

Decryption:

public void getDataFromRSA(String sendname, PrivateKey privateKey) {
    try {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(sendname)));

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        int length = 0;
        int allLength = 0;
        byte[] buffer = new byte[128];
        byte[] bufferAC = null;
        byte[] outData = null;
        byte[] allData = null;
        byte[] tmpData = null;
        while ( (length = bis.read(buffer)) != -1) {
            if (length < 128) {
                bufferAC = new byte[length];
                System.arraycopy(buffer, 0, bufferAC, 0, length);
                outData = cipher.doFinal(bufferAC);
            } else {
                outData = cipher.doFinal(buffer); // HERE IS THE ERROR
            }
            allLength += outData.length;
            tmpData = allData;
            allData = new byte[allLength];
            System.arraycopy(tmpData, 0, allData, 0, tmpData.length);
            System.arraycopy(outData, 0, allData, tmpData.length, outData.length);
        }
    } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | ClassNotFoundException | InvalidKeySpecException e) {
        e.printStackTrace();
    }
}

EDIT OK, it seems I don't know about encryption as much as I thought. I'd like to use only RSA (if it's possible) since I don't need to transfer info more than once (size of info vary). I've edited encryption like this:

int i = 0;
byte[] buffer = new byte[245];
byte[] cipherData = null;
while (i < data.length) {
    if (i+245 >= data.length) {
        buffer = new byte[data.length - i];
        System.arraycopy(data, i, buffer, 0, data.length - i);
    } else {
        System.arraycopy(data, i, buffer, 0, 245);
    }
    cipherData = cipher.update(buffer);
    bos.write(cipherData);
    i += 245;
}
bos.write(cipher.doFinal()); // HERE IS THE ERROR
bos.close();

And now I get javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes (tried several lower values for buffer size). Is it because data length is not multiple of blocksize? Could this be fixed? Thanks for answers.

3
  • You should not use RSA as block cipher. In your scheme, an attacker can simply insert a previous block anywhere in your cipher without you noticing it during decryption. Hybrid encryption/decryption is not that hard, why don't you make an effort to do it right? Commented Sep 6, 2014 at 16:46
  • For your current problem: RSA has padding overhead, you should be putting at most 245 bytes in and decrypt per 256 bytes (11 bytes overhead). If you must, use doFinal in a loop with a 245 byte encrypt buffer and a 256 byte decrypt input buffer. Note that this does not fix your protocol, just your current implementation. Commented Sep 6, 2014 at 16:50
  • Thank you, I use hybrid cryptography now without problems Commented Sep 7, 2014 at 19:26

2 Answers 2

3

First of all, you should be using hybrid encryption, i.e. first encrypt the data using a symmetric cipher and then encrypt the random secret with an RSA key - sending both to the receiver.

Second, you should never have to perform doFinal in a loop for a single message. Use update and a single doFinal instead.

And thirdly, 2048 bits is 256 bytes. As long as you keep trying to decrypt 128 bytes instead of 256, you will get this exception. Usually I use 2048 / Byte.SIZE instead, it makes the code more readable and will avoid mistakes.

Sign up to request clarification or add additional context in comments.

2 Comments

You're absolutely right. Thank you, now I learned something new in Java cryptography. I have just one question - what algorithms are save to use in plain Java (I used BouncyCastle before)? I'd like something universal. Now I use SHA-512, RSA 2048 and AES 128 (first I've tried AES/ECB/PKCS5Padding which I used with BouncyCastle but it gave me error while decryption)
Thats a strange set of parameters. You should use at least use a larger key size for RSA if you want to have a consistent level of security. See keylength.com . Never use ECB. If available, try GCM instead. OAEP would be a good idea for RSA.
0

This exception occurs when you try to encrypt data with private key and decrypt with public key, you need to reverse this or you have to use a single key to encrypt and decrypt your data. This would solve this exception.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.