添加自签名证书 OkHttpClient

Posted

技术标签:

【中文标题】添加自签名证书 OkHttpClient【英文标题】:Adding self-signed certificate OkHttpClient 【发布时间】:2019-08-23 06:16:22 【问题描述】:

我有一个需要使用 REST 连接到服务器的 android 应用程序。我对请求使用 Retrofit 2,它运行良好。 问题是当我想使用 SSL 连接时。使用 open 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】:

我从 website 修复了我的代码库

私有 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();               

【讨论】:

以上是关于添加自签名证书 OkHttpClient的主要内容,如果未能解决你的问题,请参考以下文章

向 iphone Simulator 添加自签名证书?

将自签名证书添加到iphone Simulator?

将自签名证书链添加到密钥库

添加自签名证书而不提示用户是/否

信任来自 IIS 的自签名证书

https本地自签名证书添加到信任证书访问