【发布时间】:2016-01-09 02:53:05
【问题描述】:
在我的 android 应用程序中,我需要使用 OkHttp 库向我的服务器执行一些请求。 我有一个包含四个部分的 ssl 证书:
- AddTrustExternalCARoot.crt
- COMODORSAAddTrustCA.crt
- COMODORSADomainValidationSecureServerCA.crt
- www_mydomain_com.crt
我已经在 portecle 1.9 中导入了所有部件,然后我设置了我的密钥库密码并导出了 .bks 证书。
然后我将这个 mycert.bks 插入到我的应用项目的 res/raw 文件夹中。 现在我正在尝试使用以下代码通过 https 连接到我的服务器:
OkHttpClient client = new OkHttpClient();
try{
client.setSslSocketFactory(getPinnedCertSslSocketFactory(context));
RequestBody formBody = new FormEncodingBuilder()
.add("params", "xxx")
.build();
Request request = new Request.Builder()
.url("https:\\mydomain.com")
.post(formBody)
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
return response.body().string();;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private SSLSocketFactory getPinnedCertSslSocketFactory(Context context) {
try {
KeyStore trusted = KeyStore.getInstance("BKS");
InputStream in = context.getResources().openRawResource(R.raw.mycert);
trusted.load(in, "mypass".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) {
Log.e("MyApp", e.getMessage(), e);
}
return null;
}
但我得到一个异常,这是 logcat:
10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err: javax.net.ssl.SSLPeerUnverifiedException: Hostname myserver.net not verified:
10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err: certificate: sha1/"mysha1string"
10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err: DN: CN=www.aaa.it,OU=PositiveSSL,OU=Domain Control Validated
10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err: subjectAltNames: [www.aaa.it, aaa.it]
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Connection.connectTls(Connection.java:244)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Connection.connectSocket(Connection.java:199)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Connection.connect(Connection.java:172)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:367)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:328)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:245)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Call.getResponse(Call.java:267)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:224)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:195)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Call.execute(Call.java:79)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.aaa.android.client.Login$BackgroundTask.doInBackground(Login.java:294)
10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.aaa.android.client.Login$BackgroundTask.doInBackground(Login.java:277)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:288)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at java.lang.Thread.run(Thread.java:818)
问题出在哪里?
更新: 我在这个库上做了很多尝试,我发现了这一点:
- 如果我自动向 https:\link.com OkHttp 库发出请求 信任所有证书。
- 如果我只想信任我的证书,我必须执行我认为的解决方案 贴在上面。
- 如果我不想接受所有主机,但不使用我的证书,我 可以按照 BNK 的建议使用 hostnameVerifier。
但是,如果我的解决方案有效,为什么我会发布这个问题?因为我很愚蠢,我向我的 vps url (vpsxxx.net/directory.php) 而不是我的域 (mydomain.it/directory.php) 发出请求。
显然 SSL 证书应用于我的域而不是我的 vps。
我希望这对某人有用。
P.S.:对不起我的英语! :D
【问题讨论】:
标签: android ssl https keystore okhttp