0
我試圖在Android客戶端上使用自定義證書實現SSL連接。如果我嘗試使用正常的Java程序連接到同一臺服務器(我使用系統參數導入密鑰存儲區),那麼一切正常。此外,如果我使用android方法連接到服務器,但沒有https,它工作正常。但是,一旦我用HTTPS Android的方法(如下所示的方法),它給了我這個錯誤:套接字已關閉嘗試sslException時出現異常
04-06 20:12:29.234: W/System.err(2328): java.net.SocketException: Socket is closed
04-06 20:12:29.234: W/System.err(2328): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.checkOpen(OpenSSLSocketImpl.java:237)
04-06 20:12:29.234: W/System.err(2328): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:250)
04-06 20:12:29.234: W/System.err(2328): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
04-06 20:12:29.234: W/System.err(2328): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
04-06 20:12:29.234: W/System.err(2328): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:442)
04-06 20:12:29.244: W/System.err(2328): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
04-06 20:12:29.244: W/System.err(2328): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
04-06 20:12:29.244: W/System.err(2328): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:81)
04-06 20:12:29.244: W/System.err(2328): at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:197)
04-06 20:12:29.244: W/System.err(2328): at libcore.net.http.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:281)
04-06 20:12:29.244: W/System.err(2328): at john.z.lead.utils.ServerRequest.get_response(ServerRequest.java:497)
04-06 20:12:29.244: W/System.err(2328): at john.z.lead.utils.ServerRequest.logout(ServerRequest.java:797)
04-06 20:12:29.244: W/System.err(2328): at john.z.lead.fragments.Logout_Fragment$1$1.run(Logout_Fragment.java:59)
04-06 20:12:29.244: W/System.err(2328): at java.lang.Thread.run(Thread.java:841)
我使用的代碼是:
public static JSONObject get_response(List<Parameter> params,
final String address) throws IOException, JSONException, LeadException {
// String body = "param1=" + URLEncoder.encode("value1", "UTF-8") +
// "&" +
// "param2=" + URLEncoder.encode("value2", "UTF-8");
StringBuilder body = new StringBuilder();
for (Parameter pa : params) {
body.append(pa.getKey() + "="
+ URLEncoder.encode(pa.getValue(), "UTF-8") + "&");
}
try {
URL url = new URL(address);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
if (connection instanceof HttpsURLConnection) {
KeyStore trusted = KeyStore.getInstance("BKS");
// Get the raw resource, which contains the keystore with
// your trusted certificates (root and any intermediate certs)
InputStream in = Datastore.getActiv().getResources()
.openRawResource(R.raw.truststore);
// Initialize the keystore with the provided trusted
// certificates
// Also provide the password of the keystore
trusted.load(in, "lead".toCharArray());
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(trusted);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
((HttpsURLConnection) connection)
.setSSLSocketFactory(context.getSocketFactory());
}
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length",
String.valueOf(body.length()));
OutputStreamWriter writer = new OutputStreamWriter(
connection.getOutputStream());
writer.write(body.toString());
writer.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
StringBuilder build = new StringBuilder();
for (String line; (line = reader.readLine()) != null;) {
build.append(line);
}
writer.close();
reader.close();
return new JSONObject(build.toString());
} catch (UnknownHostException | FileNotFoundException
| ConnectException e) {
Datastore.getActiv().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(
Datastore.getActiv(),
"Konnte keine Verbindung zum Server ("
+ address
+ ") herstellen.\nBitte überprüfen Sie ihre Netzwerkverbindung und/oder\nkontaktieren Sie einen Administrator",
Toast.LENGTH_LONG).show();
;
}
});
throw e;
} catch (KeyManagementException|KeyStoreException|NoSuchAlgorithmException|CertificateException e) {
MessageDialog.showMessageDialog(Datastore.getActiv(), "Es ist ein kritischer Fehler beim Herstellen der sicheren Verbindung aufgetreten");
e.printStackTrace();
throw new LeadException(LeadException.Errorcode.UNKNOWN);
}
}
但我從來沒有關閉過套接字。這個錯誤必須是由if-block內的東西引起的,因爲如果url是非https,那麼錯誤不會發生 – joz