private static byte[] rsaOpWithPrivateKey(PrivateKey javaKey, int openSSLPadding,
            int cipherMode, byte[] input) {
        String keyAlgorithm = javaKey.getAlgorithm();
        if (!"RSA".equals(keyAlgorithm)) {
            logger.warning("Unexpected key type: " + keyAlgorithm);
            return null;
        }

        String jcaPadding;
        switch (openSSLPadding) {
            case NativeConstants.RSA_PKCS1_PADDING:
                // Since we're using this with a private key, this will produce RSASSA-PKCS1-v1_5
                // (signature) padding rather than RSAES-PKCS1-v1_5 (encryption) padding
                jcaPadding = "PKCS1Padding";
                break;
            case NativeConstants.RSA_NO_PADDING:
                jcaPadding = "NoPadding";
                break;
            case NativeConstants.RSA_PKCS1_OAEP_PADDING:
                jcaPadding = "OAEPPadding";
                break;
            default:
                logger.warning("Unsupported OpenSSL/BoringSSL padding: " + openSSLPadding);
                return null;
        }

        String transformation = "RSA/ECB/" + jcaPadding;
        Cipher c;

        // Since this is a delegated key, we cannot handle providing a cipher using this key.
        // Otherwise we wouldn't end up in this class in the first place. The first step is to
        // try to get the most preferred provider as long as it isn't us.
        try {
            c = Cipher.getInstance(transformation);
            c.init(cipherMode, javaKey);

            // Ignore it if it points back to us.
            if (Conscrypt.isConscrypt(c.getProvider())) {
                c = null;
            }
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            logger.warning("Unsupported cipher algorithm: " + transformation);
            return null;
        } catch (InvalidKeyException e) {
            logger.log(Level.WARNING, "Preferred provider doesn't support key:", e);
            c = null;
        }

        // If the preferred provider was us, fall back to trying to find the
        // first not-us provider that initializes correctly.
        if (c == null) {
            List<Provider> providers = getExternalProviders("Cipher." + transformation);
            for (Provider p : providers) {
                try {
                    c = Cipher.getInstance(transformation, p);
                    c.init(cipherMode, javaKey);
                    break;
                } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
                    c = null;
                }
            }
            if (c == null) {
                logger.warning("Could not find provider for algorithm: " + transformation);
                return null;
            }
        }

        try {
            return c.doFinal(input);
        } catch (Exception e) {
            logger.log(Level.WARNING,
                    "Exception while decrypting message with " + javaKey.getAlgorithm()
                            + " private key using " + transformation + ":",
                    e);
            return null;
        }
    }
Finds providers that are not us that provide the requested algorithms.
common/src/main/java/org/conscrypt/CryptoUpcalls.java