Java SSL握手失败有时会失败,具体取决于VM参数/属性



我有一个简单的服务器类和客户端类。客户端连接到服务器,服务器只回显它接收到的任何内容。如果我在命令行上运行程序并指定密钥存储和信任存储,它可以正常工作,但当我试图在java代码中设置属性时,它似乎失败了。我需要能够设置这些是运行时,因为它将在Android程序中使用。如果有人知道问题是什么,或者知道更好的方法,我将不胜感激

我在问,当我在运行时将系统属性设置为VM的命令行参数时,是否有人知道SSL握手失败的原因。问题是属性设置不正确。

服务器:

SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket socket = (SSLServerSocket) factory.createServerSocket(9999);
SSLSocket sslsocket = (SSLSocket) socket.accept();
InputStream input = sslsocket.getInputStream();
InputStreamReader isr = new InputStreamReader(input);
BufferedReader reader = new BufferedReader(isr);
String str = null;
while ((str = reader.readLine()) != null) {
    System.out.println(str);
    System.out.flush();
}

客户:

SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) factory.createSocket("localhost", 9999);
InputStream input = System.in;
InputStreamReader isr = new InputStreamReader(input);
BufferedReader reader = new BufferedReader(isr);
OutputStream out = sslsocket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out);
BufferedWriter writer = new BufferedWriter(osw);
String str = null;
while ((str = reader.readLine()) != null) {
    writer.write(str + 'n');
    writer.flush();
}

工作良好:

$javac *.java
$java -Djavax.net.ssl.keyStore=keystore 
$-Djavax.net.ssl.keyStorePassword=changeit Server
$java -Djavax.net.ssl.trustStore=keystore 
$-Djavax.net.ssl.trustStorePassword=changeit Client < input

如果在运行时设置属性,则不起作用:

System.setProperty("-Djavax.net.ssl.trustStore", "/path/to/file/keystore");
System.setProperty("-Djavax.net.ssl.trustStorePassword", "changeit");
// also set for the server (keyStore, keyStorePassword)
$javac *.java
$java Server; java Client < input.txt

它似乎是连接的,但当我实际在客户端的控制台中键入一些内容时,它会给我以下错误:

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:1961)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at java.io.BufferedWriter.flush(BufferedWriter.java:254)
at Client.main(Client.java:38)

您设置的系统属性不正确。"-D"是一个命令行,而不是属性名称的一部分。尝试:

System.setProperty("javax.net.ssl.trustStore","/path/to/file/keystore");System.setProperty("javax.net.ssl.trustStorePassword","changeit");

按照您对其进行编码的方式,您设置了一些被SSL代码忽略的伪属性。

最新更新