我正在尝试使用用户CAC卡上的证书从Web服务客户端(Axis2)启用SSL通信。像魅力一样......直到Web服务器启用了CAC。此时,SSL连接被拒绝,并显示链中的其他证书未包含在内的错误消息。
我已确保提供程序可用,方法是将其添加到security.properties文件中或以编程方式创建它。
我目前的方法是简单地设置系统属性: System.setProperty(“javax.net.ssl.keyStore”,“NONE”); System.setProperty(“javax.net.ssl.keyStoreType”,“PKCS11”);
我从this问题/答案中了解到,此方法仅发送“最终实体”证书。显然我需要实现自己的X509KeyManager。这对我来说是个新的理由,任何人都可以建议一个很好的参考或提供如何做的样本吗?
感谢您的帮助。
答案 0 :(得分:1)
最佳密钥管理器实现取决于您希望使用的证书的颁发者。
如果用户的CAC上的证书始终由特定CA颁发,则只需将该颁发者的证书和任何中间证书存储在PKCS#7文件的上游。在getCertificateChain()
方法中,此集合可以盲目地附加到用户的证书上并返回。
如果情况不是那么简单,但可以枚举可能的发行人的完整列表,获取所有证书,他们的颁发者的证书,依此类推,直到根证书
将所有根证书作为可信条目添加到密钥库。将中间证书捆绑在PKCS-#7格式文件中。
如果您正在使用SSLEngine
,请实施X509KeyManager
(或扩展X509ExtendedKeyManager
)。具体来说,在getCertificateChain()
方法中,您将使用CertPathBuilder
创建从用户证书到受信任根的有效链。 target是您使用alias
参数从用户的CAC加载的证书。 trusted roots是您创建的信任库中的证书;中间证书可以是PKCS#7文件中的loaded和added to the builder parameters.一旦构建链,get the certificate path和convert it到一个数组。这是getCertificateChain()
方法的结果。
如果无法预测谁将颁发用户证书,您可以在运行时从LDAP目录或其他存储库获取中间证书。这是一个全新的难度级别。