在com.squareup.retrofit2:retrofit:2.0.1
上将com.squareup.okhttp3:okhttp:3.2.0
与AVD 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提供的示例代码中是否存在错误,或者我做错了什么?
答案 0 :(得分:3)
您的配置不正确。将pinningUrl
替换为固定网址的主机名。例如,您需要example.com
而不是http://example.com/
。如果您想发送PR以使主机名验证更严格,那将非常受欢迎。