-1

我有一个简单的服务器类和客户端类。客户端连接到服务器,服务器只是回显它收到的任何内容。如果我通过命令行运行程序并指定密钥库和信任库,它工作正常,但是当我尝试在 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)
4

1 回答 1

1

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

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

您对其进行编码的方式,是在设置一些被 SSL 代码忽略的虚假属性。

于 2013-06-25T17:20:44.917 回答