OkHttp javax.net.ssl.SSLPeerUnverifiedException:未验证主机名domain.com [英] OkHttp javax.net.ssl.SSLPeerUnverifiedException: Hostname domain.com not verified

查看:133
本文介绍了OkHttp javax.net.ssl.SSLPeerUnverifiedException:未验证主机名domain.com的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力让这个工作。我正在尝试使用自签名证书通过 https 连接到我的服务器。我认为现在还没有任何页面或示例。

I've been trying for days to get this working. I'm trying to connect to my server over https with a self signed certificate. I don't think there is any pages or examples that I haven't read by now.

我做了什么:


  1. 按照本教程创建bks密钥库: http://blog.crazybob.org/2010/02/android-trusting-ssl- certificates.html

  1. Created bks keystore by following this tutorial: http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

它使用 openssl s_client -connect domain.com:443从服务器获取证书。然后使用充气城堡创建一个bks密钥库。

It uses openssl s_client -connect domain.com:443 to get the certificate from the server. Then creates a bks keystore using bouncy castle.


  1. 从原始文件夹中读取创建的密钥库,将其添加到sslfactory,然后再添加到OkHttpClient。像这样:

  1. Reading created keystore from raw folder adding it to sslfactory and and then to OkHttpClient. Like this:

public ApiService() {
    mClient = new OkHttpClient();
    mClient.setConnectTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
    mClient.setReadTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
    mClient.setCache(getCache());
    mClient.setCertificatePinner(getPinnedCerts());
    mClient.setSslSocketFactory(getSSL());
}

protected SSLSocketFactory getSSL() {
    try {
        KeyStore trusted = KeyStore.getInstance("BKS");
        InputStream in = Beadict.getAppContext().getResources().openRawResource(R.raw.mytruststore);
        trusted.load(in, "pwd".toCharArray());
        SSLContext sslContext = SSLContext.getInstance("TLS");
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trusted);
        sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
        return sslContext.getSocketFactory();
    } catch(Exception e) {
        e.printStackTrace();
    }
    return null;
}

public CertificatePinner getPinnedCerts() {
    return new CertificatePinner.Builder()
            .add("domain.com", "sha1/theSha=")
            .build();
}


  • 由于某种原因,这总是产生 SSLPeerUnverifiedException 包含或不包含密钥库。有或没有 CertificatePinner

  • This for some reason this always generates a SSLPeerUnverifiedException with or without the keystore. And with or without the CertificatePinner.

    javax.net.ssl.SSLPeerUnverifiedException: Hostname domain.com not verified: 0         
     W/System.err﹕ certificate: sha1/theSha=
     W/System.err﹕ DN: 1.2.840.113549.1.9.1=#1610696e666f40626561646963742e636f6d,CN=http://domain.com,OU=development,O=domain,L=Valencia,ST=Valencia,C=ES
     W/System.err﹕ subjectAltNames: []
     W/System.err﹕ at com.squareup.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:124)
     W/System.err﹕ at com.squareup.okhttp.Connection.connect(Connection.java:143)
     W/System.err﹕ at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:185)
     W/System.err﹕ at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
     W/System.err﹕ at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
     W/System.err﹕ at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
     W/System.err﹕ at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
     W/System.err﹕ at com.squareup.okhttp.Call.getResponse(Call.java:273)
     W/System.err﹕ at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)
     W/System.err﹕ at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201)
     W/System.err﹕ at com.squareup.okhttp.Call.execute(Call.java:81)
     ...
    


  • 我做错了什么?

    推荐答案

    我终于让这个工作混合了多个答案。

    I finally got this working with a mix of multiple answers.

    首先,证书是错误的,不确定如何。但是,通过使用此答案中的脚本创建它们使它们起作用。需要的是服务器证书和密钥。然后客户端需要另一个证书。

    First, the certificates was made wrongly, not sure how. But by creating them using the script in this answer made them work. What was needed was a server certificate and a key. Then the client needed another certificate.

    要在android中使用证书,我将.pem文件转换为.crt文件,如下所示:

    To use the certificate in android I converted the .pem file to a .crt file like this:

    openssl x509 -outform der -in client.pem  -out client.crt
    

    在android中我将证书添加到我的OkHttp客户端,如下所示:

    In android I added the certificate to my OkHttp client like the following:

    public ApiService() {
        mClient = new OkHttpClient();
        mClient.setConnectTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
        mClient.setReadTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
        mClient.setCache(getCache());
        mClient.setSslSocketFactory(getSSL());
    }
    
    protected SSLSocketFactory getSSL() {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream cert = getAppContext().getResources().openRawResource(R.raw.client);
            Certificate ca = cf.generateCertificate(cert);
            cert.close();
    
            // creating a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);
    
            return new AdditionalKeyStore(keyStore);
        } catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    

    最后一部分新的AdditionalKeyStore()取自这个写得非常好的答案。这增加了一个后备密钥库。

    The last part with new AdditionalKeyStore() is taken from this very well written answer. Which adds a fallback keystore.

    我希望这可以帮助其他人!这是让HTTPS使用我找到的自签名证书的最简单方法。其他方式包括拥有一个BouncyCastle密钥库,这对我来说似乎太过分了。

    I hope this might help anyone else! This is the simplest way to get HTTPS working with a self-signed certificate that I have found. Other ways include having a BouncyCastle keystore which seems excessive to me.

    这篇关于OkHttp javax.net.ssl.SSLPeerUnverifiedException:未验证主机名domain.com的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆