Добавление самозаверяющего сертификата OkHttpClient - PullRequest
1 голос
/ 02 апреля 2019

У меня есть приложение для 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 Ответ

0 голосов
/ 04 апреля 2019

Я исправил свою кодовую базу с этого сайта

private 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();               

}

...