2016-03-29 2 views
2

Код и входыSSL: 400 не требуется сертификат был отправлен

Я пытаюсь установить соединение SSL, и я получаю 400 No required SSL certificate was sent ответ от сервера. Я делаю это стандартным способом, как описано, например, here; Я бегу Java 8.

образец моего кода будет:

OkHttpClient client  = new OkHttpClient(); 
    KeyStore keyStoreClient = getClientKeyStore(); 
    KeyStore keyStoreServer = getServerKeyStore(); 
    String algorithm  = ALGO_DEFAULT;//this is defined as "PKIX" 

    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm); 
    keyManagerFactory.init(keyStoreClient, PASSWORD_SERVER.toCharArray()); 

    SSLContext sslContext = SSLContext.getInstance("TLS"); 

    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(algorithm); 
    trustManagerFactory.init(keyStoreServer); 

    sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); 

    client.setSslSocketFactory(sslContext.getSocketFactory()); 
    client.setConnectTimeout(32, TimeUnit.SECONDS); // connect timeout 
    client.setReadTimeout(32, TimeUnit.SECONDS); // socket timeout 

    return client; 

А вот код, который я использую для отправки GET-запроса:

public String get(String url) throws IOException 
{ 
    String callUrl = URL_LIVE.concat(url); 
    Request request = new Request.Builder() 
      .url(callUrl) 
      .build(); 
    Response response = this.client.newCall(request).execute(); 
    return response.body().string(); 
} 

Я включил:

System.setProperty("javax.net.debug", "ssl"); 

Итак, чтобы увидеть отладочные сообщения - но там нет ошибок/предупреждений/предупреждений, единственное, что находится в самом конце:

main, called close() 
main, called closeInternal(true) 
main, SEND TLSv1.2 ALERT: warning, description = close_notify 
main, WRITE: TLSv1.2 Alert, length = 26 
main, called closeSocket(true) 

Это единственное, что я могу рассматривать как «ненормальный» материал (но я сомневаюсь, что это так).

Я пробовал:

  • Различные протоколы отключение/включение. Например, форсирование TLSv1/TLSv1.1 для сокета без успеха. Чтобы попробовать, я завернул свою фабрику ssl в другую фабрику, которая отключает/разрешает определенные протоколы.
  • Отключить SSLv2Hello - но это не изменение изображения.
  • Установите Oracle policies, потому что раньше были уведомления о некоторых пропущенных алгоритмах, и эта установка «решена», но общий результат все тот же.
  • Установка System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true"); - хромой, но и не стал ничего менять, кроме сообщения в журнале Allow unsafe renegotiation: true (был «ложным», очевидно)
  • Использование KeyManagerFactory.getDefaultAlgorithm() в algorithm для KeyManagerFactory.getInstance() вызова. Это вызывает исключение Get Key failed: Given final block not properly padded, и, насколько я понял, это из-за неправильного используемого алгоритма (см. this). Мой алгоритм по умолчанию: SunX509
  • Добавление сертификата непосредственно к моей машине с keytool -importcert -file /path/to/certificate -keystore keystore.jks -alias "Alias", а затем использовать это в моей программе с помощью System.setProperty("javax.net.ssl.trustStore","/path/to/keystore.jks"); с установкой пароля: System.setProperty("javax.net.ssl.trustStorePassword","mypassword"); (я установил пароль в keytool, после чего подтвердил доверенный сертификат с yes); см. this и this сообщений. С этим не возникало никаких ошибок, но проблема сохранилась.
  • Добавление сертификата в глобальное хранилище ключей (то, которое находится в JAVA_PATH/jre/lib/security/cacerts): keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias Alias -file /path/to/certificate (см. this); выглядит так, как будто операция импорта была успешной, но она не изменилась.

В отладочном состоянии также есть уведомление: ssl: KeyMgr: choosing key: 1 (verified: OK) - не уверен, что это релевантно, так как я не эксперт по SSL.

К сожалению, я не могу видеть серверные журналы, поэтому я не могу наблюдать за полной картинкой.

Вопрос

Что может быть причиной этой ошибки 400 и как я могу прогрессировать дальнейшую отладку (/ попробовать что-то еще)? Любые советы будут высоко оценены.

+1

У вас нет сертификата клиента, если вы не создали (1) пару ключей и (2) самоподписанный сертификат или (3) CSR и (4) подписали его CA, и ни одна из этих операций могут быть действительно выполнены в доверительном магазине JDK. – EJP

+0

У меня есть клиентский сертификат в формате pkcs12. Я попытался экспортировать его, что на самом деле было успешным с помощью 'keytool -importkeystore -destkeystore -srckeystore cert -srcstoretype PKCS12 -srcstorepass certPass -alias 1', и я знаю, что' certPass', который действителен, так как я могу разблокировать с ним сертификат pkcs12 и см. сертификат + закрытый ключ там –

+0

Я нашел проблему. Это как @EJP, самозаверяющий сертификат. Я все время исправил. –

ответ

2

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

Как правило, ваш сервер имеет сертификат (с ключом, установленным на «аутентификацию сервера TLS»), подписанный либо ИТ-безопасностью вашей организации, либо каким-либо глобально доверенным ЦС. Вы должны получить сертификат для проверки подлинности клиента TLS из того же источника.

Если вы захватили сообщение TLS в Wireshark, вы увидите сообщение ServerHello, за которым следует «Запрос сертификата клиента», на который вы отвечаете сообщением «Клиентский сертификат» длиной 0. Сервер решает отклонить этот запрос ,

+0

У меня есть сертификат, и я сделал: 'keytool -importcert -file/path/here -keystore keystore.jks -alias" Alias ​​", после чего я установил пароль. В моей программе я сделал: 'System.setProperty (" javax.net.ssl.trustStore ","/path/to/jks ");' и 'System.setProperty (" javax.net.ssl.trustStorePassword "," password ");" но у меня все еще такая же проблема. Правильно ли я импортирую импорт? Пробовал из [здесь] (http://stackoverflow.com/questions/4325263/how-to-import-a-cer-certificate-into-a-java-keystore) и [здесь] (http://stackoverflow.com/а/5871352/2637490) –