我正在尝试使用Java的内置HttpsServer类编写https服务器,并且在尝试连接到我使用HttpsURLConnection类编写的服务器时遇到以下异常:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1300)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.jav
客户端代码:
private void downloadFromUrl(URL url, String localFilename) throws IOException {
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
//System.setProperty("javax.net.ssl.keyStore", '/etc/keystore.ks');
System.setProperty("javax.net.ssl.keyStorePassword", "passphrase");
try
{
char[] passphrase = "passphrase".toCharArray();
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, passphrase);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, passphrase);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keyStore);
SSLContext ssl = SSLContext.getInstance("TLS");
ssl.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
HostnameVerifier hostnameVerifier = new ClientHostnameVerifier();
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
HttpsURLConnection urlSecureConn = (HttpsURLConnection) url.openConnection();
//URLConnection urlConn = url.openConnection();//connect
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(ssl.getSocketFactory());
inputStream = urlSecureConn.getInputStream(); //get connection inputstream
fileOutputStream = new FileOutputStream(localFilename); //open outputstream to local file
byte[] buffer = new byte[4096]; //declare 4KB buffer
int len;
//continue downloading and storing to local file while data is available
while ((len = inputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, len);
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (inputStream != null)
{
inputStream.close();
}
}
finally
{
if (fileOutputStream != null)
{
fileOutputStream.close();
}
}
}
}
以及初始化https服务器的代码:
public void init()
{
if(mServer == null)
{
try
{
InetSocketAddress socket = new InetSocketAddress(Integer.parseInt(LISTENED_PORT));
mServer = HttpsServer.create(socket, 0);
updateContexts();
createContentsFile();
mServer.createContext("/info.xml", new InfoXMLHandler());
//mServer.setExecutor(null); // creates a default executor
mServer.setHttpsConfigurator(new HttpsConfigurator(createSslContext()) {
public void configure (HttpsParameters params) {
SSLContext c = null;
try
{
c = getSSLContext();
SSLParameters defaultSSLParameters = c.getDefaultSSLParameters ();
params.setSSLParameters ( defaultSSLParameters );
SSLParameters sslparams = c.getDefaultSSLParameters();
params.setSSLParameters(sslparams);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
mServer.start();
}
catch(Exception e)
{
System.out.println("Exception at server initialization: " + e);
}
}
else
{
updateContexts();
}
}
我用谷歌搜索了这个问题,但我没有找到任何有用的信息