SSLHandshakeException JAVA: клиентский SSL-вызов с использованием ключа и файла сертификата

У меня есть файл сертификата и его ключ. Используя эти два, я могу успешно вызвать API данной службы с помощью почтальона.

Теперь я пытаюсь написать клиент, который должен использовать эти два и вызывать API. Прежде чем писать код Java, с помощью openssl создал файл pfx, используя существующий файл сертификата и соответствующий ему ключ. После просмотра нескольких примеров через Интернет/ переполнение стека:

private static String trustStorePath = "/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/security/cacerts";
private static final String trustStorePassword = "changeit";
private static final String keyStoreFile = "/pathTocert/mycert.pfx";
private static final String keyStorePassword = "changeit";

public static SSLSocketFactory enableSSL() {
    SSLContext context = null;
    InputStream keyInput = null, truststream = null, certInput = null;

    KeyStore trustks;
    try {

        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyInput =  new FileInputStream(new File(keyStoreFile));


        keyStore.load(keyInput, keyStorePassword.toCharArray());
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
        keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());

        trustks = KeyStore.getInstance("JKS");
        File trustcert = new File(trustStorePath);
        truststream = new FileInputStream(trustcert);
        trustks.load(truststream, trustStorePassword.toCharArray());
        truststream.close();

        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
        tmf.init(trustks);

        context = SSLContext.getInstance("TLS");
        context.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());

        return context.getSocketFactory();

    } catch (KeyStoreException e) {

        e.printStackTrace();
    } catch (IOException e) {

        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {

        e.printStackTrace();
    } catch (CertificateException e) {

        e.printStackTrace();
    } catch (UnrecoverableKeyException e) {

        e.printStackTrace();
    } catch (KeyManagementException e) {

        e.printStackTrace();
    }
    return null;

}

И после того, как я сделал это в своем основном методе, я устанавливаю SSLSocketFactory и делаю вызов https:

            URL myUrl = new URL(httpsURL);
            SSLSocketFactory sslSocketFactory = enableSSL();
             HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();

            conn.setSSLSocketFactory(sslSocketFactory);

             InputStream is = conn.getInputStream();
             InputStreamReader isr = new InputStreamReader(is);
             BufferedReader br = new BufferedReader(isr);

             String inputLine;

                while ((inputLine = br.readLine()) != null) {
                    System.out.println(inputLine);
                }

                br.close();

Я новичок в библиотеке безопасности Java, и я застрял с

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: доверенный сертификат не найден

Я уже пробовал несколько шагов, таких как установка pfx в cacerts JDK или изменение кода, указанного в URL-адресе.

Как подключиться к защищенному веб-сайту с помощью SSL в Java с файлом pkcs12?

Но до сих пор ни один из них не работал у меня. Буду признателен за любую помощь в этом. Пожалуйста, напишите в комментарии, если нужна дополнительная информация.


person Abhinav    schedule 22.01.2018    source источник
comment
Просто примечание: файл cacerts загружается по умолчанию (вам не нужно делать это явно), если только вы не хотите, чтобы некоторым дополнительным сертификатам доверяли (квалифицирован ли сертификат сервера? Подписан CA и имеет действительное имя хоста). Вы также можете использовать -Djavax.net.debug=ssl:handshake, чтобы увидеть, какие сертификаты загружены откуда (или нет)   -  person gusto2    schedule 22.01.2018