Наступні основні кроки необхідні для досягнення захищеного з'єднання з боку сертифікаційних органів, які не вважаються довіреними платформою Android.
За запитом багатьох користувачів, я відобразив тут найважливіші частини моєї статті блогу :
- Візьміть усі необхідні сертифікати (root та будь-які проміжні сертифікати)
- Створіть сховище ключів з keytool та постачальником BouncyCastle та імпортуйте серти
- Завантажте сховище ключів у додатку для android та використовуйте його для захищених з'єднань (рекомендую використовувати Apache HttpClient замість стандартного
java.net.ssl.HttpsURLConnection
(простіше зрозуміти, ефективніший)
Візьміть серти
Ви повинні отримати всі сертифікати, які будують ланцюжок від сертифікату кінцевої точки, аж до Root CA. Це означає, що будь-які (якщо вони є) проміжні сертифікати CA, а також корінь CA. Вам не потрібно отримувати сертифікат кінцевої точки.
Створіть магазин брелоків
Завантажте постачальник BouncyCastle і зберігайте його у відомому місці. Також переконайтеся, що ви можете викликати команду keytool (зазвичай розташована під папкою bin вашої установки JRE).
Тепер імпортуйте отримані серти (не імпортуйте кінцівок кінцевих точок) у форматну клавішу BouncyCastle.
Я цього не перевіряв, але думаю, що порядок імпорту сертифікатів є важливим. Це означає, що імпортуйте спочатку найнижчий проміжний сертифікат CA, а потім аж до сертифіката Root CA.
За допомогою наступної команди буде створено нову сховище ключів (якщо її ще немає) з паролем mysecret і імпортуватиме проміжний сертифікат CA. Я також визначив постачальника BouncyCastle, де його можна знайти в моїй файловій системі та форматі зберігання ключів. Виконайте цю команду для кожного сертифіката ланцюга.
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
Перевірте, чи правильно імпортовано сертифікати в сховище ключів:
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
Потрібно вивести весь ланцюг:
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
Тепер ви можете скопіювати сховище ключів як вихідний ресурс у додаток для Android під res/raw/
Скористайтеся магазином брелоків у вашому додатку
Перш за все, ми повинні створити спеціальний Apache HttpClient, який використовує нашу сховище ключів для 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);
}
}
}
Ми створили наш спеціальний HttpClient, тепер ми можемо використовувати його для безпечного з'єднання. Наприклад, коли ми робимо дзвінок GET на ресурс 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();
Це воно ;)