2016-04-26 50 views
0

AVD with Android 6.0上使用com.squareup.retrofit2:retrofit:2.0.1com.squareup.okhttp3:okhttp:3.2.0。 我试图使用由根CA签署的自签名证书实现公钥固定。该根CA位于系统CA信任存储区中。okhttp未正确验证引脚

使用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提供的示例代码中的错误还是我做错了什么?

回答

2

您正在配置不正确。将pinningUrl替换为固定URL的主机名。例如,您想要example.com而不是http://example.com/。如果你想发送一个PR来使主机名验证更加严格,这将是非常受欢迎的。

+0

我发现这个增强功能可以解决这个问题。 https://github.com/square/okhttp/issues/1653 – Tom