Mutual SSL - цепочка сертификатов клиента emtpy при использовании java в качестве клиента - PullRequest
0 голосов
/ 02 ноября 2018

Мы используем Java-клиент (openJDK 1.8.0) для вызова API, который требует взаимной аутентификации. Для этого мы используем стандартный JKS-файл java в качестве хранилища ключей и хранилища доверенных сертификатов (один и тот же файл, содержащий как trustcerts, так и удостоверения личности / privatekey). Пример Java, который мы используем для тестирования, выглядит следующим образом: *

KeyStore clientKeyStore = KeyStore.getInstance("JKS");
            clientKeyStore.load(new FileInputStream("./client.keystore"),
                    password.toCharArray());

            // create a client connection manager to use in creating httpclients
            PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager();


            SSLContext sslContext = SSLContextBuilder.create()
                    .loadKeyMaterial(clientKeyStore, password.toCharArray())
                    .loadTrustMaterial(clientKeyStore, null).build();

            // create the client based on the manager, and use it to make the call
            CloseableHttpClient httpClient = HttpClientBuilder.create()
                    .setConnectionManager(mgr)
                    .setSslcontext(sslContext)
                    .setSSLHostnameVerifier(new NoopHostnameVerifier())
                    .build();


            HttpPost httppost = new HttpPost("https://someUrl");

            String params = "";
            StringEntity param = new StringEntity(params);
            httppost.setEntity(param);
            System.out.println("Sending request...............");
            HttpResponse response = httpClient.execute(httppost);

Во время SSL-рукопожатия, как последнего шага «serverhello», сервер запрашивает личность клиента, выдав «CertificateRequest» - пожалуйста, найдите ниже запрос ::

    *** CertificateRequest
Cert Types: RSA, ECDSA, DSS
Supported Signature Algorithms: SHA512withRSA, Unknown (hash:0x6, signature:0x2), SHA512withECDSA, SHA384withRSA, Unknown (hash:0x5, signature:0x2), SHA384withECDSA, SHA256withRSA, SHA256withDSA, SHA256withECDSA, SHA224withRSA, SHA224withDSA, SHA224withECDSA, SHA1withRSA, SHA1withDSA, SHA1withECDSA
Cert Authorities:
<CN=Intermediate CA, OU=ourCA.com, O=ourCA Inc, C=US>

Сразу после этого мы видим строки ниже, указывающие на то, что keyManager java не может найти ничего, подписанного тем же подписывающим лицом.

*** ServerHelloDone
[read] MD5 and SHA1 hashes:  len = 4
0000: 0E 00 00 00                                        ....
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***

Мы проверили, что сертификат присутствует в хранилище ключей и является действительным сертификатом (открывая его в окне Windows, он не открывается, если его недействительный сертификат). Таким образом, наше хранилище ключей имеет цепочку: myIdentity >> с подписью Intermediate CA >> с подписью Root CA

Несколько вещей, которые мы попробовали (без удачи):

  • Попытка переопределения keystoremanager вернуть жестко закодированный псевдоним, т.е. псевдоним сертификата в keystore.jks
  • Попытка разделения удостоверений личности и сертификатов ЦС в двух отдельных файлах, т.е. в отдельные keystore.jks и truststore.jks

Стоит поделиться, что такая же связь работает хорошо, если мы используем cURL. В случае cURL, мы должны явно передать сертификат клиента в качестве аргумента (cURL не имеет понятия о хранилище ключей) и мы используем хранилище ключей по умолчанию в linux (/etc/pki/tls/certs/ca-bundle.crt)

curl -vvv GET https://api.someone.com/some/path -E /home/certificates/client.test.pem --key /home/certificates/client.test.key

Я не уверен, какие другие детали могут добавить ценность, но я буду рад поделиться всеми возможными необходимыми деталями (кроме моего личного ключа :-P)

1 Ответ

0 голосов
/ 19 декабря 2018

У меня была такая же проблема, как вы описали. Проблема, с которой я столкнулся, заключалась в том, что я загрузил хранилище ключей в Java, используя:

System.setProperty("javax.net.ssl.keyStore", "/path/key.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "pass");

Когда сервер запросил ClientCertificate, все, что было получено, было:

*** CertificateRequest 
Cert Types: RSA, DSS Supported Signature Algorithms: SHA512withRSA, SHA512withECDSA, SHA384withRSA, SHA384withECDSA, SHA256withRSA, SHA256withECDSA, Unknown (hash:0x4,signature:0x2), SHA224withRSA, SHA224withECDSA, Unknown (hash:0x3,signature:0x2), SHA1withRSA, SHA1withECDSA, SHA1withDSA 
Cert Authorities: 
&ltCN=HB Internal Issuing CA, DC=domainx, DC=hb, DC=bis>
*** ServerHelloDone 
Warning: no suitable certificate found - continuing without client authentication

Решением для этого было загрузить хранилище ключей другим способом, как описано: Java SSLHandshakeException "нет общих наборов шифров"

По сути, я изменил способ создания SSLContext:

От:

System.setProperty("javax.net.ssl.keyStore", "/path/key.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "pass");

System.setProperty("javax.net.ssl.trustStore", "/path/trust.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

SSLContext c = SSLContext.getInstance("TLSv1.2");
c.init(null, null, null);

Кому:

// instantiate a KeyStore with type JKS
KeyStore ks = KeyStore.getInstance("JKS");

// load the contents of the KeyStore
final char[] keyPasswd = "pass".toCharArray();
ks.load(new FileInputStream("/path/key.jks"), keyPasswd);

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

keyManagerFactory.init(ks, keyPasswd);

SSLContext c = SSLContext.getInstance("TLSv1.2");
c.init(keyManagerFactory.getKeyManagers(), null, null);

и тогда результат был:

*** CertificateRequest
Cert Types: RSA, DSS
Supported Signature Algorithms: SHA512withRSA, SHA512withECDSA, SHA384withRSA, SHA384withECDSA, SHA256withRSA, SHA256withECDSA, Unknown (hash:0x4, signature:0x2), SHA224withRSA, SHA224withECDSA, Unknown (hash:0x3, signature:0x2), SHA1withRSA, SHA1withECDSA, SHA1withDSA
Cert Authorities:
&ltCN=HB Internal Issuing CA, DC=domainx, DC=hb, DC=bis>
*** ServerHelloDone
matching alias: ibmwebspheremq01
...