我正在尝试在我的 android 应用程序中配置一个 https 客户端,该客户端将对从服务器接收到的证书链执行细粒度检查。
更准确地说,我想检查:
- 如果链包含给定的 CA 证书(自定义 CA)
- 链尾证书的公用名和组织名的值
我虽然这可以通过使用正确构造的 CertPathTrustManagerParameters 初始化 TrustManagerFactory 来完成,但此代码片段的第二行:
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(new CertPathTrustManagerParameters(pkixBuilderParameters));
抛出以下异常:
Unsupported spec: javax.net.ssl.CertPathTrustManagerParameters@634b748.
Only android.security.net.config.RootTrustManagerFactorySpi$ApplicationConfigParameters supported.
从这篇文章:https ://security.stackexchange.com/questions/83372/what-is-the-difference-of-trustmanager-pkix-and-sunx509 我了解 Android JSSE 提供程序可能不支持使用 CertPathTrustManagerParameters 初始化 TrustManagerFactory。
我想知道是否可以在 Android 上使用 CertPathTrustManagerParameters 初始化 TrustManagerFactory。
我的问题的备用解决方案是使用包含我的 CA 证书的 KeyStore 初始化 TrustManagerFactory 并覆盖生成的 TrustManager 的checkServerTrusted(X509Certificate[] chain, String authType)函数,添加对组织和公用名的检查。
笔记 :
不管调用时指定的算法
TrustManagerFactory tmf = TrustManagerFactory.getInstance(String algorithm)
返回的 TrustManagerFactory 对象始终设置为RootTrustManagerFactorySpi作为 TrustManagerFactorySpi。
然后,函数
tmf.init(new CertPathTrustManagerParameters(pkixBuilderParameters))
在 RootTrustManagerFactorySpi 中调用以下函数:
@Override
public void engineInit(ManagerFactoryParameters spec)
throws InvalidAlgorithmParameterException {
if (!(spec instanceof ApplicationConfigParameters)) {
throw new InvalidAlgorithmParameterException("Unsupported spec: " + spec + ". Only "
+ ApplicationConfigParameters.class.getName() + " supported");
}
mApplicationConfig = ((ApplicationConfigParameters) spec).config;
}
这表明,当使用ManagerFactoryParameters 初始化时,TrustManagerFactory 只接受要提供的ApplicationConfigParameters并拒绝CertPathTrustManagerParameters(两者都是 ManagerFactoryParameters 的子类)