2

在 SO 上提出 SSL 固定问题似乎是在向空洞大喊大叫,但这里……

我需要在 Android 上实现 SSL 固定,并且我正在处理一些要求/约束​​:

  1. 它应该验证整个证书链,而不仅仅是叶子。
  2. 它需要与 Volley 库一起使用

根据 Google 的教程,我想出了以下用于创建 SSLSocketFactory 的实现:

CertificateFactory factory = CertificateFactory.getInstance("X.509");

final KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);    
keyStore.setCertificateEntry("leaf_cert", getCertificate(factory, R.raw.leaf_cert));
keyStore.setCertificateEntry("interm_cert1", getCertificate(factory, R.raw.interm_cert1));
keyStore.setCertificateEntry("interm_cert2", getCertificate(factory, R.raw.interm_cert2));
keyStore.setCertificateEntry("root_cert", getCertificate(factory, R.raw.root_cert));

final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);

final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());

return sslContext.getSocketFactory();

当我创建一个新HttpStack实例时使用这个 SSLSocket 工厂。请注意,我按照它们在链中的位置顺序列出了证书。

为了验证此代码,我利用 Google 的nogotofailAndroid 演示应用程序修改了NoSslCertificateChainOfTrustCheckTest. 看起来固定工作正常,但我实际上只需要包含leaf_certKeyStore. 使用openssl,我验证服务器只发回叶证书。在这一点上,事情变得非常奇怪:

  • 我的团队构建的姊妹 iOS 应用程序使用 AFNetworking 来完成证书固定繁重的工作,它实际上强制所有四个证书都存在。换句话说,尽管只取回了叶子证书,但它正在验证整个链
  • 当我实际尝试在项目中使用代码时(再次使用 Volley),我发现我不仅不需要整个证书链,我只需要包含leaf_cert OR iterm_cert1即可。

总而言之,我需要回答以下问题:

  • 我的钉扎实现真的能完成它的工作吗?
  • 验证整个链条需要什么魔法?
  • 为什么我可以用中间证书代替叶子证书,为什么我只能使用 Volley 而不是 in nogotofail
4

0 回答 0