okhttp没有正确验证引脚

时间:2016-04-26 19:46:26

标签: android ssl ssl-certificate retrofit okhttp

com.squareup.retrofit2:retrofit:2.0.1上将com.squareup.okhttp3:okhttp:3.2.0AVD with Android 6.0一起使用。 我尝试使用由根CA签名的自签名证书来实现公钥锁定。 Root CA位于系统CA信任库中。

使用okhttp wiki提供的示例进行一些小改动:

OkHttpClient client = new OkHttpClient.Builder().certificatePinner(
                new CertificatePinner.Builder()
                        .add(pinningUrl, "sha256/invalidPIN")
                        .build()).build();
Request request = new Request.Builder()
                .url(pinningUrl)
                .build();
Response response = client.newCall(request).execute();

if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
for (Certificate certificate : response.handshake().peerCertificates()) {
  System.out.println(CertificatePinner.pin(certificate));
}

发生的事情是response.isSuccessful返回true,虽然引脚不正确,但不会引发异常。唯一正确完成的是使用系统CA信任库中的根CA验证证书。

我发现它正在工作,就是在for循环之前添加这一行。但这不是正确的方法,因为请求已经发送,固定应该在TLS协商完成之前工作。在我找到的任何示例代码中都没有提到这一行。

client.certificatePinner().check(pinningUrl, response.handshake().peerCertificates());

引发

javax.net.ssl.SSLPeerUnverifiedException: Certificate pinning failure!

okhttp提供的示例代码中是否存在错误,或者我做错了什么?

1 个答案:

答案 0 :(得分:3)

您的配置不正确。将pinningUrl替换为固定网址的主机名。例如,您需要example.com而不是http://example.com/。如果您想发送PR以使主机名验证更严格,那将非常受欢迎。