【问题标题】:Adding self-signed certificate OkHttpClient添加自签名证书 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 未找到证书路径的信任锚。

你能帮我用我的证书和密钥创建我的客户端吗!

【问题讨论】:

    标签: java android ssl certificate


    【解决方案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();               
    

    }

    【讨论】:

      猜你喜欢
      • 2023-04-02
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-05
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多