все еще получает фатальное предупреждение: bad_certificate, - PullRequest
0 голосов
/ 21 мая 2018

у меня есть ключ и сертификат (объединены) в один файл cert.pem, и я получаю «исключение»: «javax.net.ssl.SSLHandshakeException», «message»: «Получено фатальное предупреждение: bad_certificate», pem file is right, but i think problem is how i generating jks keystore file.

.pem формат сертификата

НАЧАТЬ СЕРТИФИКАТ

...

КОНЕЦ СЕРТИФИКАТ

НАЧАТЬ СЕРТИФИКАТ

...

КОНЕЦ СЕРТИФИКАТА

НАЧАТЬ RSA ЧАСТНЫЙ КЛЮЧ

...

END RSA ЧАСТНЫЙ КЛЮЧ ### `

объединить его с командой команды keytool:

keytool -import -trustcacerts -alias yourdomain -file combined.pem -keystore yourkeystore.jks

код Java

public class HttpsTrustManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
        // TODO Auto-generated method stub

    }

    @Override
    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
        // TODO Auto-generated method stub

    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[]{};
    }
}

запрос

FileInputStream instream = new FileInputStream(
      new File(this.resourcePath()+"/path_to.jks")
  );
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(instream, "password".toCharArray());

    SSLContext sslContext = SSLContexts.custom()
            .loadKeyMaterial(keyStore, "password".toCharArray()) // use null as second param if you don't have a separate key password
            .build();

    sslContext.init(null,new X509TrustManager[]{new HttpsTrustManager()}, new SecureRandom());


    HttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();
    HttpResponse response = httpClient.execute(
            new HttpPost("https://url")
    );
    HttpEntity entity = response.getEntity();

    System.out.println("----------------------------------------");
    System.out.println(response.getStatusLine());
    EntityUtils.consume(entity);

1 Ответ

0 голосов
/ 22 мая 2018

Когда вы используете Apache SSLContexts.custom().loadKeyMaterial().build(), он инициализирует встроенный контекст указанным хранилищем ключей и доверенным менеджером по умолчанию.Затем вы вызываете sslContext.init() на re - инициализируете его с помощью no keymanager и указанного доверенного менеджера;это игнорирует и отбрасывает предварительную инициализацию.В результате ваш контекст не имеет менеджера ключей и не может выполнять аутентификацию клиента.

Вы должны быть последовательными.Либо используйте Apache и дайте (одному и тому же) компоновщику оба loadKeyMaterial и loadTrustMaterial, соответствующие тому, что вы хотите - в частности, httpclient 4.5.4 добавляет org.apache.http.conn.ssl.TrustAllStrategy, который реализует "пусть все воры и мошенники увидят и поменяют мои предположительно безопасные данные ".В качестве альтернативы используйте JSSE для непосредственного создания SSLContext с .getInstance() и .init() it (один раз!) С вашим доверенным менеджером с нулевой безопасностью и менеджером ключей, созданным из вашего хранилища ключей (и явного SecureRandom, если хотите, но если выпропустите, что это по умолчанию).

Однако это может не сработать, поскольку указанная вами команда keytool является правильной, только если yourdomain был ранее существующим PrivateKeyEntry, соответствующим цепочке сертификатов, которую вы импортировали в нее.Используйте keytool -list -alias yourdomain, чтобы убедиться, что это PrivateKeyEntry, а НЕ TrustedCertEntry.Если нет, и если вам нужно использовать приватный ключ из файла PEM (а не тот, который уже находится в хранилище ключей), вам необходимо сначала преобразовать цепочку сертификатов и в PKCS12 с OpenSSL, а затем в зависимости от вашегоJava может преобразовать PKCS12 в JKS с помощью keytool.Для этого в нескольких стеках есть десятки Q (и As).

...