@Override protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { if (input != null) { engineUpdate(input, inputOffset, inputLen); } if (inputTooLarge) { throw new IllegalBlockSizeException("input must be under " + buffer.length + " bytes"); } final byte[] tmpBuf; if (bufferOffset != buffer.length) { if (padding == NativeCrypto.RSA_NO_PADDING) { tmpBuf = new byte[buffer.length]; System.arraycopy(buffer, 0, tmpBuf, buffer.length - bufferOffset, bufferOffset); } else { tmpBuf = Arrays.copyOf(buffer, bufferOffset); } } else { tmpBuf = buffer; } byte[] output = new byte[buffer.length]; int resultSize; if (encrypting) { if (usingPrivateKey) { resultSize = NativeCrypto.RSA_private_encrypt( tmpBuf.length, tmpBuf, output, key.getPkeyContext(), padding); } else { resultSize = NativeCrypto.RSA_public_encrypt( tmpBuf.length, tmpBuf, output, key.getPkeyContext(), padding); } } else { try { if (usingPrivateKey) { resultSize = NativeCrypto.RSA_private_decrypt( tmpBuf.length, tmpBuf, output, key.getPkeyContext(), padding); } else { resultSize = NativeCrypto.RSA_public_decrypt( tmpBuf.length, tmpBuf, output, key.getPkeyContext(), padding); } } catch (SignatureException e) { IllegalBlockSizeException newE = new IllegalBlockSizeException(); newE.initCause(e); throw newE; } } if (!encrypting && resultSize != output.length) { output = Arrays.copyOf(output, resultSize); } bufferOffset = 0; return output; }