OkHttp 信任证书
OkHttp trusting certificate
在我的 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.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.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.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
让我们假设您的服务器应用程序托管在一台服务器机器中,该机器具有服务器证书,例如,"Issued to"
是 "localhost"
。然后,在 verify
方法中你可以验证 "localhost"
。
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
HostnameVerifier hv =
HttpsURLConnection.getDefaultHostnameVerifier();
return hv.verify("localhost", session);
}
};
您可以通过以下链接阅读更多内容:
-
It is to be used during a handshake if the URL's hostname does not match the peer's identification hostname.
Common Problems with Hostname Verification
One reason this can happen is due to a server configuration error. The
server is configured with a certificate that does not have a subject
or subject alternative name fields that match the server you are
trying to reach...
然后,您可以通过调用 client.setHostnameVerifier(hostnameVerifier);
在您的应用中使用主机名验证器。希望这对您有所帮助!
P/S:另一个临时解决方法是 return true;
在 verify
方法中,但是,不推荐这样做。
在我的 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.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.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.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
让我们假设您的服务器应用程序托管在一台服务器机器中,该机器具有服务器证书,例如,"Issued to"
是 "localhost"
。然后,在 verify
方法中你可以验证 "localhost"
。
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
HostnameVerifier hv =
HttpsURLConnection.getDefaultHostnameVerifier();
return hv.verify("localhost", session);
}
};
您可以通过以下链接阅读更多内容:
-
It is to be used during a handshake if the URL's hostname does not match the peer's identification hostname.
Common Problems with Hostname Verification
One reason this can happen is due to a server configuration error. The server is configured with a certificate that does not have a subject or subject alternative name fields that match the server you are trying to reach...
然后,您可以通过调用 client.setHostnameVerifier(hostnameVerifier);
在您的应用中使用主机名验证器。希望这对您有所帮助!
P/S:另一个临时解决方法是 return true;
在 verify
方法中,但是,不推荐这样做。