Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
证书固定在Android上不适用于OkHttp_Android_Ssl_Ssl Certificate_Retrofit_Okhttp - Fatal编程技术网

证书固定在Android上不适用于OkHttp

证书固定在Android上不适用于OkHttp,android,ssl,ssl-certificate,retrofit,okhttp,Android,Ssl,Ssl Certificate,Retrofit,Okhttp,在Android应用程序上使用com.squareup.okhttp:okhttp:2.4.0和com.squareup.改型:改型:1.9.0,尝试通过HTTPS与服务器REST API通信,该API使用自签名证书 服务器密钥库有一个私钥和两个证书,即服务器的证书和一个根证书openssl s_客户端输出- Certificate chain 0 s:/C=...OU=Dev/CN=example.com i:/C=... My CA/emailAddress=info@example

在Android应用程序上使用
com.squareup.okhttp:okhttp:2.4.0
com.squareup.改型:改型:1.9.0
,尝试通过HTTPS与服务器REST API通信,该API使用自签名证书

服务器密钥库有一个私钥和两个证书,即服务器的证书和一个根证书<代码>openssl s_客户端输出-

Certificate chain
 0 s:/C=...OU=Dev/CN=example.com
   i:/C=... My CA/emailAddress=info@example.com
 1 s:/C=... My CA/emailAddress=info@example.com
   i:/C=... My CA/emailAddress=info@example.com
在Android应用程序中,OkHttp使用根证书的SHA1签名进行初始化-

CertificatePinner certificatePinner = new CertificatePinner.Builder()
        .add("example.com", "sha1/5d...3b=")
        .build();

OkHttpClient client = new OkHttpClient();
client.setCertificatePinner(certificatePinner);

RestAdapter restAdapter = new RestAdapter.Builder()
        .setEndpoint("https://example.com")
        .setClient(new OkClient(client))
        .build();
但当尝试发送请求时,异常失败-

retrofit.RetrofitError: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395)
        at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
        at java.lang.reflect.Proxy.invoke(Proxy.java:397)
        at $Proxy1.report(Unknown Source)
        ...
        at android.os.AsyncTask$2.call(AsyncTask.java:288)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:818)
 Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:306)
        at com.squareup.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103)
        at com.squareup.okhttp.Connection.connect(Connection.java:143)
        at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:185)
        at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
        at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
在尝试
sslSocket.startHandshake()
时,甚至在使用
CertificatePaner
检查接收到的证书之前,它就被抛出到
com.squareup.okhttp.internal.http.SocketConnector

我已使用
openssl
curl--cacert root.pem
确保服务器正确安装了证书


那么,为什么OkHttp在尝试检查提供的证书是否正常之前抛出异常呢

OkHttp不支持自签名证书

使用由已知CA签名的证书时,握手成功,然后
certificatePaner
确保证书链至少包含一个提供的签名。如果没有出现异常,它将抛出异常,停止请求


因此,可以使用由已知CA签名的证书并锁定其中一个证书,以确保我们与正确的服务器通信。

OkHttp确实支持自签名证书。


请检查以了解如何创建仅信任您的证书的
SslSocket

是的。证书固定不会取代现有的证书验证;它是对它的补充。您需要将客户端配置为信任您的证书;测试中有很多例子@JesseWilson和@Kof:我可以问一个问题吗,
一个已知的CA
是否意味着一个成功安装在Android手机上的CA(我可以在
可信凭证-用户
中看到它?很可能,这是一个CA,设备的签名已安装在其可信CA数据库中。另一个查看示例代码的地方是OkHttp的recipe repo:。它提供了更通用的工作代码。