Android platformunun güvenilir olduğu düşünülmeyen Sertifika Yetkililerinden güvenli bir bağlantı elde etmek için aşağıdaki ana adımlar gereklidir.
Birçok kullanıcının istediği gibi, blog makalemdeki en önemli kısımları burada yansıttım :
- Gerekli tüm sertifikaları (kök ve ara CA'lar) alın
- Keytool ve BouncyCastle sağlayıcısı ile bir anahtar deposu oluşturun ve sertifikaları içe aktarın
- Anahtar deposunu android uygulamanıza yükleyin ve güvenli bağlantılar için kullanın ( standart yerine Apache HttpClient kullanmanızı öneririz
java.net.ssl.HttpsURLConnection
(anlaşılması daha kolay, daha fazla performans)
Sertifikaları al
Uç nokta sertifikasından Kök CA'ya kadar bir zincir oluşturan tüm sertifikaları edinmeniz gerekir. Bu, varsa (varsa) Ara CA sertifikaları ve ayrıca Kök CA sertifikası anlamına gelir. Uç nokta sertifikası almanıza gerek yoktur.
Anahtar deposunu oluşturma
BouncyCastle Sağlayıcısını indirin ve bilinen bir yerde saklayın. Ayrıca keytool komutunu da çağırabildiğinizden emin olun (genellikle JRE kurulumunuzun bin klasörü altında bulunur).
Şimdi elde edilen sertifikaları (uç nokta sertifikasını içe aktarmayın) BouncyCastle biçimli bir anahtar deposuna içe aktarın.
Test etmedim, ancak sertifikaları içe aktarma sırasının önemli olduğunu düşünüyorum. Bu, önce en alt ara CA sertifikasını sonra da Kök CA sertifikasına kadar alın.
Aşağıdaki komutla, mysecret parolasıyla yeni bir anahtar deposu (önceden yoksa) oluşturulur ve Ara CA sertifikası içe aktarılır. Ayrıca dosya sistemimde ve anahtar deposu biçiminde bulunabilecek BouncyCastle sağlayıcısını tanımladım. Zincirdeki her sertifika için bu komutu yürütün.
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
Sertifikaların anahtar deposuna doğru şekilde aktarılıp aktarılmadığını doğrulayın:
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
Tüm zinciri çıktılamalıdır:
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
Artık anahtar deposunu android uygulamanızda ham kaynak olarak kopyalayabilirsiniz. res/raw/
Uygulamanızdaki anahtar deposunu kullanın
Her şeyden önce, anahtar depomuzu HTTPS bağlantıları için kullanan özel bir Apache HttpClient oluşturmanız gerekir:
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);
}
}
}
Özel HttpClient'imizi oluşturduk, şimdi güvenli bağlantılar için kullanabiliriz. Örneğin, bir REST kaynağına GET çağrısı yaptığımızda:
// 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();
Bu kadar ;)