#java #android #ssl #certificate
#java #Android #ssl #сертификат
Вопрос:
У меня есть приложение для Android, которому необходимо подключиться к серверу с помощью REST. Я использую Retrofit 2 для запросов, и это работает хорошо. Проблема в том, что я хочу использовать SSL-соединение. При открытом ssl у меня есть client.crt, myPrivateKey.pem и request.csr. У меня также есть RootCA, который я использовал для шифрования сертификата клиента и сервера.
Когда я проверяю онлайн, я нахожу множество решений с файлами одного CA.
Это код, который у меня есть на данный момент.
// https://developer.android.com/training/articles/security-ssl.html#java
private OkHttpClient initClient(boolean ssl) {
if (ssl) {
SSLSocketFactory sslSocketFactory = null;
X509TrustManager x509TrustManager = null;
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream certificateFileCRT = mContext.getResources().openRawResource(R.raw.client);
Certificate certCRT = cf.generateCertificate(certificateFileCRT);
System.out.println("ca=" ((X509Certificate) certCRT).getSubjectDN());
certificateFileCRT.close();
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", certCRT);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
x509TrustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{x509TrustManager}, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (CertificateException |IOException | KeyStoreException | NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
return new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.sslSocketFactory(sslSocketFactory, x509TrustManager)
.build();
// return getUnsafeOkHttpClient();
} else {
return new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.build();
}
}
Когда я отправляю запрос клиенту, я получаю java.security.cert.CertPathValidatorException привязка доверия для пути сертификации не найдена.
Не могли бы вы, пожалуйста, помочь мне создать мой клиент с моим сертификатом и моим ключом!
Ответ №1:
Я исправил свою кодовую базу с этого веб-сайта
частный OkHttpClient initClient() вызывает исключение KeyStoreException, CertificateException, исключение NoSuchAlgorithmException, исключение IOException, исключение UnrecoverableKeyException, исключение KeyManagementException {
// Trust self signed certificate
InputStream certificateFileCRT = mContext.getResources().openRawResource(R.raw.server);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(certificateFileCRT);
String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);
// KeyStore containing client certificate
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream fis = mContext.getResources().openRawResource(R.raw.client);
keyStore.load(fis, "PASSWORD".toCharArray());
// Build an SSL context
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, "PASSWORD".toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyManagers, trustManagers, null);
return new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.sslSocketFactory(sslContext.getSocketFactory())
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
})
.build();
}