我几天来一直在努力让它发挥作用。我正在尝试通过以下方式连接到我的服务器https带有自签名证书。我认为现在没有任何页面或示例是我未读过的。
我做了什么:
- 按照本教程创建了 bks 密钥库:http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html
It uses openssl s_client -connect domain.com:443
从服务器获取证书。然后使用 bouncy castle 创建一个 bks 密钥库。
-
从原始文件夹中读取创建的密钥库,将其添加到 sslfactory,然后添加到 OkHttpClient。像这样:
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
.
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)
...
我究竟做错了什么?
我遇到了同样的问题,但是我需要我的应用程序在多个临时环境中工作,所有这些环境都有自签名证书。更糟糕的是,他们可以即时更改这些证书。
为了解决这个问题,当仅连接到登台时,我添加了一个信任所有证书的 SSLSocketFactory。这修复了 java 错误,但是它给我留下了此票证中注明的 okhttp 异常。
为了避免此错误,我需要向 okHttpClient 添加一项自定义设置。这为我解决了错误。
okHttpClient.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)