Вы инициализируете свой SSLContext
с помощью массива null
KeyManager
.
Ключ-менеджер - это то, что обрабатывает сертификат сервера (на стороне сервера), и это то, вероятно, для установки при использовании javax.net.ssl.keyStore
.
Однако, как описано в Справочном руководстве JSSE , использование null
для первого параметра не делает то, что вам кажется подумать, что это делает:
Если параметр KeyManager [] имеет значение NULL, то для этого контекста будет определен пустой KeyManager. Если параметр TrustManager [] равен NULL, установленным поставщикам безопасности будет поиск наивысшей приоритетной реализации TrustManagerFactory, из которой будет получен соответствующий TrustManager. Аналогично, параметр SecureRandom может быть нулевым, и в этом случае будет использоваться реализация по умолчанию.
blockquote>Пустое
KeyManager
не содержит сертификатов RSA или DSA. Поэтому все блоки шифрования по умолчанию, которые будут полагаться на такой сертификат, будут отключены. Вот почему вы получаете все эти сообщения « Игнорирование недоступных сообщений шифра », что в конечном итоге приводит к сообщению об « без шифрования вообще ».Если вы хотите, чтобы ваше хранилище ключей использовалось в качестве хранилища ключей, вам нужно загрузить его и инициализировать KeyManagerFactory с помощью него:
KeyStore ks = KeyStore.getInstance("JKS"); InputStream ksIs = new FileInputStream("..."); try { ks.load(ksIs, "password".toCharArray()); } finally { if (ksIs != null) { ksIs.close(); } } KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory .getDefaultAlgorithm()); kmf.init(ks, "keypassword".toCharArray());
Использовать
kmf.getKeyManagers()
в качестве первого параметра дляSSLContext.init()
.Для двух других параметров, поскольку вы явно не запрашиваете аутентификацию клиентского сертификата, вы должны оставить доверительный менеджер значением по умолчанию (
null
) вместо копирования / вставки доверительного менеджера, который является потенциальную причину уязвимости, и вы также можете использовать значение по умолчаниюnull
SecureRandom
.
Похоже, вы пытаетесь подключиться с помощью TLSv1.2, который не широко используется на серверах. Поддерживает ли ваша цель tls1.2?
Для отладки при запуске java добавьте, как указано:
-Djavax.net.debug=ssl
, после чего вы можете увидеть, что браузер пытался использовать TLSv1, а Jetty 9.1.3 говорил TLSv1.2, чтобы они не обменивались данными. Это Firefox. Chrome хотел SSLv3, поэтому я добавил это также.
sslContextFactory.setIncludeProtocols( "TLSv1", "SSLv3" ); <-- Fix
sslContextFactory.setRenegotiationAllowed(true); <-- added don't know if helps anything.
Я не использовал большинство других вещей, которые сделал плакат оригинала:
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {
или этот ответ:
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
.getDefaultAlgorithm());
или
.setEnabledCipherSuites
Я создал один самоподписанный сертификат следующим образом: (но я добавил .jks к имени файла) и прочитал это в моем java-коде Jetty. http://www.eclipse.org/jetty/documentation/current/configuring-ssl.html
keytool -keystore keystore.jks -alias jetty -genkey -keyalg RSA
first & amp; lastname * .mywebdomain.com
Получив это исключение, я углубился в исходный код JRE. Стало очевидно, что сообщение довольно вводит в заблуждение. Он мог означать, что он говорит, но в более общем смысле это означает, что сервер не имеет данных, которые ему нужно для ответа на запрос запрошенным способом. Это может произойти, например, если сертификаты отсутствуют в хранилище ключей или не были сгенерированы с соответствующим алгоритмом. Действительно, учитывая набор шифров, которые установлены по умолчанию, нужно было бы пойти на несколько длин, чтобы действительно получить это исключение из-за отсутствия общих наборов шифров. В моем конкретном случае я создал сертификаты с алгоритмом DSA по умолчанию, когда мне нужно было заставить сервер работать с Firefox, был RSA.
Эта проблема может быть вызвана неправильной манипуляцией разрешенными наборами шифров на клиенте или на сервере, но я подозреваю, что наиболее распространенной причиной является сервер, у которого нет закрытого ключа и сертификата вообще.
NB:
ssl.setEnabledCipherSuites(sc.getServerSocketFactory().getSupportedCipherSuites());
Избавьтесь от этой строки. Ваш сервер уже не уверен в безопасности с этим небезопасным TrustManager
. Затем запустите ваш сервер с помощью -Djavax.net.debug=SSL,handshake,
, попробуйте подключиться и опубликуйте полученный результат здесь.
Сервер
import java.net.*;
import java.io.*;
import java.util.*;
import javax.net.ssl.*;
import javax.net.*;
class Test{
public static void main(String[] args){
try{
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(null,null,null);
SSLServerSocketFactory serverSocketFactory = context.getServerSocketFactory();
SSLServerSocket server = (SSLServerSocket)serverSocketFactory.createServerSocket(1024);
server.setEnabledCipherSuites(server.getSupportedCipherSuites());
SSLSocket socket = (SSLSocket)server.accept();
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
System.out.println(in.readInt());
}catch(Exception e){e.printStackTrace();}
}
}
Клиент
import java.net.*;
import java.io.*;
import java.util.*;
import javax.net.ssl.*;
import javax.net.*;
class Test2{
public static void main(String[] args){
try{
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(null,null,null);
SSLSocketFactory socketFactory = context.getSocketFactory();
SSLSocket socket = (SSLSocket)socketFactory.createSocket("localhost", 1024);
socket.setEnabledCipherSuites(socket.getSupportedCipherSuites());
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeInt(1337);
}catch(Exception e){e.printStackTrace();}
}
}
server.setEnabledCipherSuites (server.getSupportedCipherSuites ()); socket.setEnabledCipherSuites (socket.getSupportedCipherSuites ()); [/ д2]
В моем случае я получил эту ошибку no cipher suites in common
, потому что я загрузил файл формата p12
в хранилище ключей сервера вместо файла jks
.