Kesalahan SSL Android HttpGet (Tidak ada sertifikat rekan) ATAU (Koneksi ditutup oleh rekan) kesalahan
Saya mencoba melakukan HttpGet sederhana untuk membaca halaman web. Saya sudah mencoba di iOS dan berhasil di Android melalui http, tetapi tidak di https.
Urlnya adalah IP jaringan internal dan port khusus, jadi saya bisa membaca dengan http seperti ini menggunakan jalur http://ipaddress:port/MyPage.html
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpResponse response;
String responseString = null;
try {
// Try connection
HttpGet get = new HttpGet(params[0].path);
get.addHeader("Authorization",
"Basic "
+ Base64.encodeBytes(new String(params[0].username + ":" + params[0].password)
.getBytes()));
response = httpclient.execute(get);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else {
// Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.e(TAG, "ClientProtocolException");
this.e = e;
} catch (IOException e) {
Log.e(TAG, "IOException");
this.e = e;
}
return responseString;
Ketika saya mencoba menggunakan https, saya mendapatkan kesalahan No peer certificate
. Jadi saya telah mencoba menggunakan kode ini:
HttpClient httpclient = new DefaultHttpClient(httpParameter);
private HttpClient createHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https", sf, 8080));
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
return new DefaultHttpClient(conMgr, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
tetapi ini memberi saya kesalahan Koneksi ditutup oleh rekan
.
Apa yang saya lakukan salah? Saya dapat mengabaikan sertifikat dengan aman, karena ini adalah jaringan internal dengan sertifikat yang ditandatangani sendiri, namun saya tidak memiliki kendali atas vert dan pengguna aplikasi saya mungkin memiliki sertifikat yang berbeda, jadi saya harus menerima atau melewatinya secara otomatis.
Terima kasih
EDIT ------------------------------
Setelah mencoba jawaban My-Name-Is di bawah ini: Saya telah membuat kelas CustomX509TrustManager seperti yang disarankan, lalu membuat HttpClient kustom dengan menggunakan kelas tersebut seperti ini:
private HttpClient sslClient(HttpClient client) {
try {
CustomX509TrustManager tm = new CustomX509TrustManager();
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new MySSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = client.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", ssf, 8080));
return new DefaultHttpClient(ccm, client.getParams());
} catch (Exception ex) {
return null;
}
}
Dan terakhir gunakan HttpClient ini seperti ini:
private class httpGETTask extends AsyncTask<GetParams, Void, String> {
private Exception e = null;
@Override
protected String doInBackground(GetParams... params) {
// Set connection parameters
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 15000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 15000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
Log.v(TAG, params[0].path);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
httpclient = sslClient(httpclient);
HttpResponse response;
String responseString = null;
try {
// Try connection
HttpGet get = new HttpGet(params[0].path);
get.addHeader("Authorization",
"Basic "
+ Base64.encodeBytes(new String(params[0].username + ":" + params[0].password)
.getBytes()));
response = httpclient.execute(get);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else {
// Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.e(TAG, "ClientProtocolException");
this.e = e;
} catch (IOException e) {
Log.e(TAG, "IOException");
this.e = e;
}
return responseString;
Jalur yang dicatat adalah dalam format https://ipaddress:8080/Page.html
Tetapi saya mendapatkan kesalahan Koneksi ditutup oleh rekan
:
05-24 08:20:32.500: E/ConnectionHelper(1129): IOException 05-24 08:20:32.550: E/ConnectionHelper(1129): Pengecualian memuat konten 05-24 08:20:32.550: E/ConnectionHelper(1129): javax.net.ssl.SSLException: Sambungan ditutup oleh peer 05-24 08:20:32.550: E/ConnectionHelper(1129): di org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method) 05-24 08:20:32.550: E/ConnectionHelper(1129): di org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.(OpenSSLSocketImpl.java:643) 05-24 08:20:32.550: E/ConnectionHelper(1129): di org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:614) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.io.SocketInputBuffer.(SocketInputBuffer.java:70) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:172) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 05-24 08:20:32.550: E/ConnectionHelper(1129): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 05-24 08:20:32.550: E/ConnectionHelper(1129): at com.d_apps.my_app.connection_helpers.ConnectionHelper$httpGETTask.doInBackground(ConnectionHelper.java:114)
Sumber berikut ini seharusnya dapat memperbaiki masalah Anda.
Jika Anda menggunakan sertifikat "Tidak Dipercaya" (pengembang), maka di bawah ini adalah solusinya. Kita perlu mempercayai semua sertifikat, dan di bawah ini adalah cara untuk melakukannya. Untuk sertifikat tepercaya, ini berfungsi tanpa menambahkan fungsionalitas di bawah ini, kita hanya perlu mengubah http ke https dan itu akan berfungsi.
Berikut adalah solusi untuk sertifikat yang tidak dipercaya.
Dalam cara HttpClient, Anda harus membuat kelas khusus dari org.apache.http.conn.ssl.SSLSocketFactory, bukan yang org.apache.http.conn.ssl.SSLSocketFactory itu sendiri
contohnya adalah seperti ...
dan gunakan kelas ini ketika membuat instance HttpClient.
Periksa tanggal perangkat Anda. Anda mungkin telah mengubahnya ke tahun yang berbeda. Saya selalu mengalami masalah ini ketika anak-anak menggunakan ponsel saya.