简体   繁体   中英

Getting BadPaddingException when trying to decrypt - Java

I have this method for encryption:

private byte[] encrypt(byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
        BadPaddingException {
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.ENCRYPT_MODE, myPublicKey);
    ByteArrayInputStream input = new ByteArrayInputStream(data);
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    byte[] buffer = new byte[64];
    int bytes;
    ByteArrayOutputStream aux;
    try {
        while ((bytes = input.read(buffer)) != -1) {
            aux = new ByteArrayOutputStream();
            aux.write(buffer, 0, bytes);
            byte[] fragment = aux.toByteArray();
            byte[] encryptedFragment = cipher.doFinal(fragment);
            output.write(encryptedFragment);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    byte[] result = output.toByteArray();
    return result;
}

And this one for decryption:

public static String decrypt(byte[] data) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, IOException {
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.DECRYPT_MODE, myPrivateKey);
    int bitLenght = ((java.security.interfaces.RSAPrivateKey) privateKey).getModulus().bitLength();
    int blockSize = bitLenght / 8;
    byte[] buffer = new byte[blockSize];
    int bytes;
    byte[] decrypted;
    ByteArrayOutputStream aux;
    ByteArrayInputStream input = new ByteArrayInputStream(data);
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    while ((bytes = input.read(buffer)) != -1) {
        aux = new ByteArrayOutputStream();
        aux.write(buffer, 0, bytes);
        byte[] fragment = aux.toByteArray();

        byte[] decryptedFragment = cipher.doFinal(fragment);
        output.write(decryptedFragment);
    }
    decrypted = output.toByteArray();

    return new String(decrypted);
}

But I'm getting this exception:

javax.crypto.BadPaddingException: Decryption error

As I can see I've configured the Cipher to have the same PKCS1Padding so I can't guess why I'm getting that error.

I've created my private key as follows:

openssl genrsa -out myPrivateKey.key 2048

And the public one:

openssl rsa -in myPrivateKey.pem -pubout -out myPublicKey.key

As far as I can see with that command they are both PKCS1, in fact my private key starts with -----BEGIN RSA PRIVATE KEY----- .

What am I missing?

NOTE: I've also tried with blockSize = 64 , same result.

Encrypting a stream - correctly you should have cipher.update(..) in the loop and .doFinal(..) called only once after processing all data.

When decrypting if you call doFinal on a partial message you may get the exception. Regardless that it is not apparent from your code if that is the issue you face. (assuming you have the keypair correcly imported)

And indeed RSA is intended only for short (117 bytes) messages. Otherwise you may search for "hybrid encryption"

PS: the way your process the streams and arrays is screaming for optimalization, so have a look at it too, but that is for different question

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM