Untuk tujuan pengujian, saya mencoba menambahkan pabrik soket ke klien okHttp saya yang mempercayai segalanya saat proxy disetel. Ini telah dilakukan berkali-kali, tetapi implementasi saya dari pabrik soket tepercaya tampaknya kehilangan sesuatu:
class TrustEveryoneManager implements X509TrustManager {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}
OkHttpClient client = new OkHttpClient();
final InetAddress ipAddress = InetAddress.getByName("XX.XXX.XXX.XXX"); // some IP
client.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipAddress, 8888)));
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = new TrustManager[]{new TrustEveryoneManager()};
sslContext.init(null, trustManagers, null);
client.setSslSocketFactory(sslContext.getSocketFactory);
Tidak ada permintaan yang dikirim dari aplikasi saya dan tidak ada pengecualian yang dicatat sehingga tampaknya gagal secara diam-diam dalam okHttp. Setelah penyelidikan lebih lanjut, tampaknya ada Pengecualian yang ditelan di okHttp Connection.upgradeToTls()
saat jabat tangan dipaksa. Pengecualian yang diberikan kepada saya adalah:javax.net.ssl.SSLException: SSL handshake terminated: ssl=0x74b522b0: SSL_ERROR_ZERO_RETURN occurred. You should never see this.
Kode berikut menghasilkan SSLContext
yang berfungsi seperti pesona dalam membuat SSLSocketFactory yang tidak menampilkan pengecualian apa pun:
protected SSLContext getTrustingSslContext() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
final SSLContextBuilder trustingSSLContextBuilder = SSLContexts.custom()
.loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true; // Accepts any ssl cert whether valid or not.
}
});
return trustingSSLContextBuilder.build();
}
Masalahnya adalah saya mencoba menghapus semua dependensi Apache HttpClient dari aplikasi saya sepenuhnya. Kode yang mendasari dengan Apache HttpClient untuk menghasilkan SSLContext
tampaknya cukup mudah, tetapi saya jelas kehilangan sesuatu karena saya tidak dapat mengkonfigurasi saya SSLContext
untuk mencocokkan ini.
Adakah yang bisa menghasilkan implementasi SSLContext yang melakukan apa yang saya inginkan tanpa menggunakan Apache HttpClient?
sumber
java.net.SocketTimeoutException: Read timed out
Jawaban:
Untuk berjaga-jaga jika ada yang jatuh di sini, satu-satunya solusi yang berhasil untuk saya adalah membuat hal
OkHttpClient
serupa yang dijelaskan di sini .Ini kodenya:
sumber
SSL
tidakTLS
?X509TrustManager.getAcceptedIssuers()
harus mengembalikan larik kosong, bukannull
. Untuk informasi lebih lanjut, lihat komit ini (gulir ke bawah dan lihat catatan di bawah RealTrustRootIndex.java).Handshake failed
pengecualian. Ada saran?Metode berikut tidak digunakan lagi
Pertimbangkan untuk memperbaruinya menjadi
sumber
Perbarui OkHttp 3.0,
getAcceptedIssuers()
fungsinya harus mengembalikan array kosong, bukannull
.sumber
Sumber: Dokumentasi OkHttp
sumber
sslContext
asalnyasslContext
?Ini adalah solusi sonxurxo di Kotlin, jika ada yang membutuhkannya.
sumber
Saya membuat fungsi ekstensi untuk Kotlin. Tempel di mana pun Anda suka dan impor saat membuat
OkHttpClient
.gunakan seperti ini:
sumber
Ini adalah solusi Scala jika ada yang membutuhkannya
}
sumber
Anda tidak boleh mencoba menimpa validasi sertifikat dalam kode! Jika Anda perlu melakukan pengujian, gunakan CA internal / pengujian dan instal sertifikat root CA di perangkat atau emulator. Anda dapat menggunakan BurpSuite atau Charles Proxy jika tidak tahu cara menyiapkan CA.
sumber