Код и входы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) пару ключей и (2) самоподписанный сертификат или (3) CSR и (4) подписали его CA, и ни одна из этих операций могут быть действительно выполнены в доверительном магазине JDK. – EJP
У меня есть клиентский сертификат в формате pkcs12. Я попытался экспортировать его, что на самом деле было успешным с помощью 'keytool -importkeystore -destkeystore -srckeystore cert -srcstoretype PKCS12 -srcstorepass certPass -alias 1', и я знаю, что' certPass', который действителен, так как я могу разблокировать с ним сертификат pkcs12 и см. сертификат + закрытый ключ там –
Я нашел проблему. Это как @EJP, самозаверяющий сертификат. Я все время исправил. –