我正在尝试基于客户端服务器的ssl,
这是我的服务器代码:
public static void main(String arg[]){
try {
KeyStore keyStore = KeyStore.getInstance("jks");
InputStream inputStream;
try {
inputStream = new FileInputStream(ITestEncryptionConstants.SSLKEYSTORE);
keyStore.load(inputStream,
ITestEncryptionConstants.SSLPASSWORD.toCharArray());
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance("PKIX", "SunJSSE");
trustManagerFactory.init(keyStore);
X509TrustManager x509TrustManager = null;
for (TrustManager trustManager : trustManagerFactory.getTrustManagers())
{
if (trustManager instanceof X509TrustManager) {
x509TrustManager = (X509TrustManager) trustManager;
break;
}
}
KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance("SunX509", "SunJSSE");
keyManagerFactory.init(keyStore,
ITestEncryptionConstants.SSLPASSWORD.toCharArray());
X509KeyManager x509KeyManager = null;
for (KeyManager keyManager : keyManagerFactory.getKeyManagers()) {
if (keyManager instanceof X509KeyManager) {
x509KeyManager = (X509KeyManager) keyManager;
break;
}
}
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(new KeyManager[]{x509KeyManager},
new TrustManager[]{x509TrustManager}, null);
SSLServerSocketFactory factory =
sslContext.getServerSocketFactory();//(SSLServerSocketFactory )
SSLServerSocketFactory .getDefault();
SSLServerSocket sslSock =
(SSLServerSocket)factory.createServerSocket(8096);
SSLSocket c = (SSLSocket)sslSock.accept();
PrintWriter out =new PrintWriter(c.getOutputStream(),true);
InputStream in = c.getInputStream();
in.close();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchProviderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (KeyStoreException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
这是我的客户代码:
public static void main(String[] args) {
try{
// // register a https protocol handler - this may be required for previous JDK versions
//
System.setProperty("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");
System.out.println("Ok passed.");
//connect to google
SSLSocketFactory factory = (SSLSocketFactory)
SSLSocketFactory.getDefault();
SSLSocket sslSock = (SSLSocket) factory.createSocket("localhost",8096);
//send HTTP get request
PrintWriter out = new PrintWriter(sslSock.getOutputStream(), true);
BufferedReader in = new BufferedReader(new
InputStreamReader(sslSock.getInputStream()));
out.println("--------------------------> It works!!!");
System.out.println("Written to server.");
// read response
StringBuffer buf = new StringBuffer();
String line = "";
while ((line = in.readLine()) != null) {
System.out.println("Received : " + line);
buf.append(line);
}
System.out.println("Read from server: " + buf.toString());
in.close();
out.close();
// Close connection.
sslSock.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
但是我在客户端遇到以下错误:
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
有人可以帮助我的代码出错吗?
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
at sun.security.ssl.SSLSocketImpl.checkEOF(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at ripl.jing.security.encryptor.tlsservice.TestJingClient.main(TestJingClient.java:85)
Caused by: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
答案 0 :(得分:1)
(对不起,我刚刚对EJP现已删除的答案发表评论。)
服务器代码说:
SSLSocket c = (SSLSocket)sslSock.accept();
PrintWriter out =new PrintWriter(c.getOutputStream(),true);
InputStream in = c.getInputStream();
in.close();
out.close();
也就是说,I / O流(以及套接字)在接受套接字后立即关闭。因此,客户端上出现的错误消息表明连接已被远程方关闭,这不应该让人感到意外。
这或多或少与this question中的问题相同:只是获取I / O流,而不尝试从它们读取/写入,并且不尝试任何其他动作来隐式触发握手(从流或尝试获取SSLSession
)或显式(调用startHandshake
)意味着握手不会在服务器上启动。因此,客户端抛出此异常,因为连接在它已启动的握手过程中被中断。
答案 1 :(得分:0)
我不知道你正在谈论什么证书,或者有什么变化,但这里唯一的问题是你从客户端发送一条从未读过的行,而你&# 39;重新读取客户端中从未发送过的一行。当对等体已经关闭连接时发送从未读取的数据会导致连接重置。
NB自十九年前的Java 1.4以来,你还没有必要设置java.protocol.handler.pkgs
。您可以通过
System.setProperty("javax.net.ssl.keyStore", ITestEncryptionConstants.SSLKEYSTORE);
System.setProperty("javax.net.ssl.keyStorePassword", ITestEncryptionConstants.SSLPASSWORD);
SSLContext sslContext = SSLContext.getDefault();
SSLServerSocketFactory factory =
sslContext.getServerSocketFactory();//(SSLServerSocketFactory )
该行:
SSLServerSocketFactory .getDefault();
什么也没做。