SSLConnectionSocketFactory всегда возвращает 400 (двусторонний сертификат клиента ssl) Сертификаты не получены

У меня есть ssl-соединение (двухстороннее рукопожатие), и я не могу понять, почему следующие процедуры кода 400 (openJdk 11, файл p12 и пароль, предоставленные сервером, файл cer, предоставленный сервером),

Я создал файл jks из файла cer с помощью следующей команды:

keytool -importcert -file example-api.cer -keystore example-api.jks

Код

    File keyFile = new File(Objects.requireNonNull(exampleController.class.getClassLoader().
            getResource("example-client-api1.p12")).getFile());
    File trustFile = new File(Objects.requireNonNull(exampleController.class.getClassLoader().
            getResource("example-api.jks")).getFile());
    KeyStore keyStore  = KeyStore.getInstance("PKCS12");
    try(FileInputStream inStream = new FileInputStream(keyFile)) {
        keyStore.load(inStream, "password".toCharArray());
    }
    SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(trustFile, "password".toCharArray() ,new TrustAllStrategy()).
                            loadKeyMaterial(keyStore , "password".toCharArray()).build();
    HostnameVerifier hostnameVerifier = new NoopHostnameVerifier();
    SSLConnectionSocketFactory socketFactory =
            new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
    CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLHostnameVerifier(hostnameVerifier)
            .setSSLSocketFactory(socketFactory)
            .useSystemProperties()
            .build();
    HttpGet httpget = new HttpGet("https://example-api/link?token=@Secret_Token@");

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

    return  httpclient.execute(httpget);

Приведенный выше код всегда возвращает 400 (требуемый сертификат SSL не был отправлен).

но работает следующий завиток (на IOS):

curl https://example-api/link?token=@secret_token@ --cacert ./example-api-ca.crt --cert ./example-client-api1.p12:password

Любая помощь будет принята с благодарностью

Возможно, useSystemProperties() использовал свойства системы вместо вашей конкретной конфигурации. Попробуйте удалить это

pedrofb 28.10.2018 18:51

@pedrofb привет, не повезло, это не помогло, я хочу добавить одну вещь: мы действительно получили файл .crt с сервера и преобразовали его в файл .cer Base 64 (в Windows), а затем использовали файл cer, может ли это вызвать проблему? я должен использовать ЭЛТ?

Roie Beck 28.10.2018 20:27

Необходимо добавить сертификат сервера или корневой сертификат ЦС в хранилище доверенных сертификатов. Это не проблема. Вы получили ошибку, управляемую сервером, поэтому канал SSL был установлен, но без предоставления сертификата клиента. Эта проблема обычно возникает из-за неправильной конфигурации хранилища ключей, содержащего сертификат клиента. Также проверьте путь к файлу

pedrofb 28.10.2018 21:05

(1) какое промежуточное ПО используется в вашей сборке curl? проверьте, что curl -V (верхний регистр vee) (2) запускается с помощью sysprop javax.net.debug=ssl и / или получите трассировку проводов с помощью wirehark или аналогичного и сравните центры сертификации, запрошенные сервером, с теми, которые находятся в цепочке вашего сертификата (в P12 для последнего) ( 3) большинство людей используют суффикс .crt как для DER, так и для PEM (который не является точно base64) и .cer для DER, но MS использует оба для обоих, а java keytool -importcert принимает оба, плюс TrustAll все равно игнорирует ваше хранилище доверенных сертификатов

dave_thompson_085 29.10.2018 00:17

@pedrofb, я выполнил следующее: keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias test -file gravityx-api-ca.cer Предупреждение: используйте параметр -cacerts для доступа к хранилищу ключей cacerts Сертификат был добавлен в хранилище ключей проблема не устранена.

Roie Beck 29.10.2018 08:02

@ dave_thompson_085, рабочий вывод curl -V: curl -V curl 7.54.0 (x86_64-apple-darwin16.0) libcurl / 7.54.0 SecureTransport zlib / 1.2.8 Протоколы: файл dict ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp Возможности: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz UnixSockets

Roie Beck 29.10.2018 08:03

@ dave_thompson_085 В логах: javax.net.ssl ​​| SunX509KeyManagerImpl.java: 164 | найден ключ для: Пример клиентского api ("сертификат": {"версия": "v1", "серийный номер": "02", "подпись алгоритм »:« SHA1withRSA »,« эмитент »:« CN = gravity.capital, OU = X, O = Gravity Capital, L = Сидней, C = AU »,« не раньше »:« 2018-10-03 17:25 : 04.000 IDT "," не после ":" 2028-09-30 17: 25: 04.000 IDT "," subject ":" CN = api1, O = 1, C = IL "," открытый ключ субъекта ":" RSA "}) Похоже, он нашел мой ключ в cacerts

Roie Beck 29.10.2018 09:29

Обновление во время отладки я обнаружил (в журнале): добавление в качестве доверенных сертификатов («сертификат»: {«версия»: «v1», «серийный номер»: «02», «алгоритм подписи»: «SHA1withRSA», «эмитент» : "CN = gravity.capital, OU = X, O = Gravity Capital, L = Сидней, C = AU", "не до": "2018-10-03 17: 25: 04.000 IDT", "не после": «2028-09-30 17: 25: 04.000 IDT», «subject»: «CN = api1, O = 1, C = IL», «открытый ключ субъекта»: «RSA»})

Roie Beck 29.10.2018 17:47

а затем: найденный ключ для: gravityx ("сертификат": {"версия": "v1", "серийный номер": "02", "алгоритм подписи": "SHA1withRSA", "эмитент": "CN = gravity.capital , OU = X, O = Gravity Capital, L = Сидней, C = AU "," не раньше ":" 2018-10-03 17: 25: 04.000 IDT "," не после ":" 2028-09-30 17 : 25: 04.000 IDT "," subject ":" CN = api1, O = 1, C = IL "," открытый ключ субъекта ":" RSA "})

Roie Beck 29.10.2018 17:48

так что, если он вернет 400 (без сертификата), не означает ли это, что предоставленный им сертификат неверен?

Roie Beck 29.10.2018 17:50

Рой: (1) добавьте дополнительную информацию, отредактировав вопрос, особенно, когда это нужно форматировать, как это; Политика стека заключается в том, что комментарии являются временными и могут быть удалены (2) SecureTransport не является одним из известных мне промежуточных программ, извините (3) «найденный ключ для» означает, что ключ и сертификат были найдены в вашем хранилище ключей, а не в вашем хранилище доверенных сертификатов, тем более в хранилище доверенных сертификатов по умолчанию cacerts - но это не значит, что это был использовал; Я сказал, чтобы посмотреть на ту часть журнала (или трассировку), где сервер указывает, какой ЦС он хочет

dave_thompson_085 30.10.2018 07:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
11
283
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо Итак, после нескольких разочаровывающих дней: Я не знаю причины, но проблема заключалась в дефисе char ('-') в имени хоста URL-адреса, удаление знака дефиса устраняет проблему, не знаю, почему, но, опубликовав это все равно, возможно, кто-то сможет объяснить это явление. Пример (с использованием приведенного выше кода):

example-api -> not working
example.api -> Works OK

Другие вопросы по теме