Langkah-langkah utama berikut ini diperlukan untuk mencapai koneksi aman dari Otoritas Sertifikasi yang tidak dianggap dipercaya oleh platform android.
Seperti yang diminta oleh banyak pengguna, saya telah mencerminkan bagian terpenting dari artikel blog saya di sini:
- Raih semua sertifikat yang diperlukan (root dan CA perantara)
- Buat keystore dengan keytool dan penyedia BouncyCastle dan impor sertifikat
- Muat keystore di aplikasi Android Anda dan gunakan untuk koneksi yang aman (saya sarankan untuk menggunakan Apache HttpClient alih-alih standar
java.net.ssl.HttpsURLConnection
(lebih mudah dimengerti, lebih banyak performan)
Raih sertifikat tersebut
Anda harus mendapatkan semua sertifikat yang membangun rantai dari sertifikat titik akhir hingga Root CA. Ini berarti, setiap (jika ada) CA CA menengah dan juga CA CA Root. Anda tidak perlu mendapatkan sertifikat titik akhir.
Buat keystore
Unduh Penyedia BouncyCastle dan simpan ke lokasi yang diketahui. Juga pastikan bahwa Anda dapat menjalankan perintah keytool (biasanya terletak di bawah folder bin instalasi JRE Anda).
Sekarang impor sertifikat yang diperoleh (jangan impor sertifikat titik akhir) ke dalam keystore yang diformat BouncyCastle.
Saya tidak mengujinya, tetapi saya pikir urutan mengimpor sertifikat itu penting. Ini berarti, impor sertifikat CA Menengah paling bawah terlebih dahulu dan kemudian sampai ke sertifikat CA Root.
Dengan perintah berikut, keystore baru (jika belum ada) dengan kata sandi mysecret akan dibuat dan sertifikat CA Menengah akan diimpor. Saya juga mendefinisikan penyedia BouncyCastle, di mana dapat ditemukan pada sistem file saya dan format keystore. Jalankan perintah ini untuk setiap sertifikat dalam rantai.
keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret
Verifikasi apakah sertifikat diimpor dengan benar ke dalam keystore:
keytool -list -keystore "res/raw/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret
Haruskah mengeluarkan seluruh rantai:
RootCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93
IntermediateCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43
Sekarang Anda dapat menyalin keystore sebagai sumber daya mentah di aplikasi Android Anda di bawah res/raw/
Gunakan keystore di aplikasi Anda
Pertama-tama kita harus membuat Apache HttpClient kustom yang menggunakan keystore kita untuk koneksi HTTPS:
import org.apache.http.*
public class MyHttpClient extends DefaultHttpClient {
final Context context;
public MyHttpClient(Context context) {
this.context = context;
}
@Override
protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Register for port 443 our SSLSocketFactory with our keystore
// to the ConnectionManager
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
private SSLSocketFactory newSslSocketFactory() {
try {
// Get an instance of the Bouncy Castle KeyStore format
KeyStore trusted = KeyStore.getInstance("BKS");
// Get the raw resource, which contains the keystore with
// your trusted certificates (root and any intermediate certs)
InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
try {
// Initialize the keystore with the provided trusted certificates
// Also provide the password of the keystore
trusted.load(in, "mysecret".toCharArray());
} finally {
in.close();
}
// Pass the keystore to the SSLSocketFactory. The factory is responsible
// for the verification of the server certificate.
SSLSocketFactory sf = new SSLSocketFactory(trusted);
// Hostname verification from certificate
// http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
return sf;
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
Kami telah membuat HttpClient kustom kami, sekarang kami dapat menggunakannya untuk koneksi yang aman. Misalnya ketika kami melakukan panggilan GET ke sumber daya REST:
// Instantiate the custom HttpClient
DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpGet get = new HttpGet("https://www.mydomain.ch/rest/contacts/23");
// Execute the GET call and obtain the response
HttpResponse getResponse = client.execute(get);
HttpEntity responseEntity = getResponse.getEntity();
Itu dia ;)