我在StackOverflow上到处搜索,但这些问题似乎与我的不同,我在修复它时遇到了很多麻烦。
现在,我的程序应该只使用SSL套接字建立客户端 - 服务器连接,客户端只发送一条消息并关闭(我稍后会向其中添加更多内容)
我遇到了消息部分和No Cipher Suites in Common错误的问题。下面我将发布我的服务器和客户端代码以及输出。我使用的是Ubuntu 16.04和Netbeans 8.2
服务器代码:
public static void main(String[] args)
throws IOException, KeyStoreException, NoSuchAlgorithmException,
CertificateException, UnrecoverableKeyException, KeyManagementException {
FileInputStream keyFile = new FileInputStream(archivoKey);//Server.jks with Client.crt and .key as well as Server.crt and .key
char[] archivopwd = mypassword.toCharArray();
String password = mypassword;
System.setProperty("javax.net.ssl.trustStore", archivoKey);
System.setProperty("javax.net.ssl.trustStorePassword", password);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(keyFile, archivopwd);
KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, archivopwd);
KeyManager keyManagers[] = keyManagerFactory.getKeyManagers();
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, null, null);
SSLServerSocketFactory factory=(SSLServerSocketFactory)
SSLServerSocketFactory.getDefault();
SSLServerSocket ss = (SSLServerSocket) factory.createServerSocket(6000);
System.out.println("Esperando conexion...");
ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
SSLSocket so =(SSLSocket) ss.accept();
so.startHandshake();
System.out.println("Conexion realizada");
BufferedReader in = new BufferedReader
(new InputStreamReader(so.getInputStream()));
String msg = in.readLine();
System.out.println(msg);
}
服务器输出:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: no cipher suites in common
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:292)
at sun.security.ssl.ServerHandshaker.chooseCipherSuite(ServerHandshaker.java:1045)
at sun.security.ssl.ServerHandshaker.clientHello(ServerHandshaker.java:741)
at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:224)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at servidorseguridad.ServidorSeguridad.main(ServidorSeguridad.java:73)
客户端代码
public static void main(String[] args) {
int port = 6000;
String host = "localhost";
String password = mypassword;
System.setProperty("javax.net.ssl.trustStore", archivoKey);
System.setProperty("javax.net.ssl.trustStorePassword", password);
try {
SSLContext sc = SSLContext.getInstance("TLS");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream keyFile = new FileInputStream(archivoKey); //Client.jks, exactly the same as the Server.jks
try {
keyStore.load(keyFile, archivopwd);
} finally {
if (keyFile != null) {
keyFile.close();
}
}
KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, archivopwd);
sc.init(null, null, null);
SocketFactory factory = sc.getSocketFactory();
System.out.println("Buscando conexion...");
try (SSLSocket so = (SSLSocket) factory.createSocket(host, port)) {
so.getEnabledCipherSuites();
so.startHandshake();
System.out.println("Conexion exitosa!");
DataOutputStream os = new DataOutputStream(so.getOutputStream());
os.writeUTF("Prueba!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
客户端输出
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at clienteseguridad.ClienteSeguridad.main(ClienteSeguridad.java:65)
大多数东西(比如System.setProperty的东西)让我测试了我在这里读过的几个选项。 .jks是通过将crt和密钥文件获取到p12并将其添加到.jks来生成的。
我真的没有想法,所以任何帮助都表示赞赏。你需要的任何其他东西你都可以问。谢谢
答案 0 :(得分:0)
此异常通常表示服务器没有私钥。这意味着它只能支持匿名密码套件,如果客户端不允许这样,那么就没有共同的密码套件。
您的设置代码很奇怪:
您需要创建服务器端密钥库,密钥对,然后
最后:
ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
删除此行。这是不安全的。永远不要这样做。