Подтвердить что ты не робот

Подключитесь к сайту https с данным сертификатом p12

Серверная сторона предоставила мне файл сертификата .p12, который я нажал и установил на своей машине, а затем я могу получить доступ к сайту HTTPS через браузер. Теперь они хотят, чтобы я сканировал их сайт с предоставленным сертификатом. Я застрял на самом первом этапе, пытаясь получить inputStream из httpsURLConnection. На сайте нет логина. Он проверяет, есть ли у вас сертификат или нет.

Что я сделал до сих пор, так это использовать Firefox для экспорта сертификата в формате .crt. Затем я использовал команду keytool для ее импорта (файл .crt, а не .p12) в java keystore. Затем в коде:

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
File ksFile = new File(keystorePath);
in = new FileInputStream(ksFile);
ks.load(in, "changeit".toCharArray());
X509Certificate cert = (X509Certificate) ks.getCertificate(certificateAlias);

SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

HttpsURLConnection con = (HttpsURLConnection) (new URL(urlString)).openConnection();
con.connect();
con.getInputStream();
con.disconnect();

getInputStream() предоставит мне 403 запрещенный доступ к ошибкам. Я искал другие связанные темы и на самом деле гораздо более смущен, чем перед их чтением. Буду признателен за ответы.

Дополнительная информация:

  • Я только что создал экземпляр сертификата и не позволяю программе знать какие-либо ключи (частные, общедоступные и т.д.). Поэтому я считаю, что должен предоставить эти ключи серверу, давая понять, что я действительно держу сертификат. Я абсолютно не знаю, как это сделать, и логики, и синтаксиса мудры.
  • Я попробовал команду keytool для импорта файла сертификата .p12 в хранилище ключей, но каким-то образом параметр -pkcs12 не распознается keytool. Любая идея о том, как напрямую использовать этот сертификат .p12, также будет отличной.
  • trustAllCert - это массив из одного элемента TrustMangers, который ничего не проверяет (доверяйте всем). Я не знаю, буду ли я продолжать использовать это. Фактически, теперь у меня на самом деле есть один сертификат, которому можно доверять. Каков правильный способ создания TrustManger в этом случае?
  • У меня нет контроля над сервером. Все, что мне было предоставлено, это URL-адрес для доступа к их сайту, который находится под протоколом HTTPS, и сертификат .p12. На сайте нет логина. Если сертификат установлен, я могу войти.
4b9b3361

Ответ 1

Если вы хотите попытаться настроить конфигурацию SSL, вы можете использовать предоставленный вам файл P12 без необходимости его преобразования в JKS. Кроме того, вам нужно будет использовать закрытый ключ в P12, а не только сертификаты, которые вы скопировали в JKS. Не уверен, что это будет соответствовать вашим потребностям напрямую, но это может привести вас к правильному пути:

        KeyStore clientStore = KeyStore.getInstance("PKCS12");
        clientStore.load(new FileInputStream("test.p12"), "testPass".toCharArray());

        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(clientStore, "testPass".toCharArray());
        KeyManager[] kms = kmf.getKeyManagers();

        KeyStore trustStore = KeyStore.getInstance("JKS");
        trustStore.load(new FileInputStream("cacerts"), "changeit".toCharArray());

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);
        TrustManager[] tms = tmf.getTrustManagers();

        SSLContext sslContext = null;
        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kms, tms, new SecureRandom());

        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
        URL url = new URL("https://www.testurl.com");

        HttpsURLConnection urlConn = (HttpsURLConnection) url.openConnection();

Конфигурирование trustStore таким образом является необязательным. Вы можете создать JKS со всеми сертификатами в цепочке вашего P12 или просто убедиться, что они находятся в вашем файле JRE cacerts. Что касается keytool, для справки, вы можете запускать команды keytool на P12 (указать -storetype pkcs12), но не можете импортировать P12 в JKS. Вы также не можете экспортировать только ключ из P12 с помощью команды keytool.

На данный момент у меня нет настроек серверов, чтобы проверить этот код, поэтому дайте ему шанс и посмотрите, все ли вы получаете ошибку 403.

Ответ 2

Добавление этого в качестве ответа, поскольку мне нужно больше места для записи.

Во-первых, возникает вопрос: подписан ли сертификат доверенным органом, например Verisign? Если это не так, доверительный магазин должен иметь сертификат CA (обычно это файл .pem), который делает сертификат p12 "действительным". Хранилище доверия java по умолчанию содержит большинство (если не все) сертификатов CA от крупных компаний, таких как Verisign и Thawte.

Кроме того, вы можете протестировать свое приложение для подключения к безопасному серверу без кодирования конфигурации SSL, но с некоторыми параметрами командной строки, например:

java -Djavax.net.ssl.keyStore=[path_to_p12_cert] \
 -Djavax.net.ssl.keyStorePassword=[p12_password] \
 -Djavax.net.ssl.keyStoreType=PKCS12 \
 -Djavax.net.ssl.trustStore=[path_to_trust_store_with_CA_certificates] \
 -Djavax.net.ssl.trustStorePassword=[trust_store_password] \
 [MainClass]

а затем ваш код будет просто

HttpsURLConnection con = (HttpsURLConnection) (new URL(urlString)).openConnection();
con.connect();
con.getInputStream();
con.disconnect();

Если вы чувствуете мазохистство, JSSE ref guide - это весело.

Ответ 3

Это то, что сработало для меня:

   KeyStore keyStore  = KeyStore.getInstance("PKCS12");
    FileInputStream instream = new FileInputStream(new File("client-p12-keystore.p12"));
    try {
        keyStore.load(instream, "password".toCharArray());
    } finally {
        instream.close();
    }

    // Trust own CA and all self-signed certs
    SSLContext sslcontext = SSLContexts.custom()
        .loadKeyMaterial(keyStore, "password".toCharArray())
        //.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
        .build();
    // Allow TLSv1 protocol only
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslcontext,
        SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    CloseableHttpClient httpclient = HttpClients.custom()
        .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
        .setSSLSocketFactory(sslsf)
        .build();
    try {

        HttpGet httpget = new HttpGet("https://localhost:8443/secure/index");

        System.out.println("executing request" + httpget.getRequestLine());

        CloseableHttpResponse response = httpclient.execute(httpget);
        try {
            HttpEntity entity = response.getEntity();

            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            if (entity != null) {
                System.out.println("Response content length: " + entity.getContentLength());
            }
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    } finally {
        httpclient.close();
    }
}

Ответ 4

Простая команда keytool будет экспортировать ваше хранилище .p12 в .jks keystore:

keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore keystore.jks