Java 中的 SSL 证书验证

IT小君   2021-12-22T02:05:22

假设我编写了两个 Java 应用程序:Ping.jar并且Pong.jar它们在两个单独的服务器上部署和运行(Ping.jar部署到srv-01.myorg.comPong.jar部署到srv-02.myorg.com),这两个应用程序需要通过 SSL 相互通信(2 路)。我们还假设每个应用程序都有自己的 SSL 证书。

  • 作为 Java 程序员,我如何编码PingPong验证彼此的 SSL 证书?每个 CA 是否都提供某种我可以使用的 RESTful API,例如,HttpClientJava 是否有自己的证书验证 API?是否有我可以使用的开源第三方 JAR 或服务?

当我在网上搜索这个时,我惊讶地发现它很少出现。

评论(4)
IT小君

如果您使用 Java SE SSL/TLS 类(例如SSLSocketSSLEngine)进行连接,则您使用的是Java 安全套接字扩展 (JSSE)

它将根据SSLContext用于创建此SSLSocketSSLEngine.

SSLContext将根据TrustManager应如何建立信任的指示进行初始化

除非您需要特定配置,否则您通常可以依赖默认值:这将依赖 PKIX 算法 (RFC 3280) 根据一组信任锚(cacerts默认情况下)验证证书cacerts,Oracle JRE 附带的是一个 JKS 密钥库,您可以向其中添加其他证书。您可以使用keytool例如显式添加证书

您还可以以X509TrustManager编程方式创建基于自定义密钥库的密钥库(如本答案中所述),并在SSLContext不影响默认密钥库的特定情况下使用它

除此之外,如果您使用自己的协议,则需要验证您获得的证书是否与您要查找的主机名匹配(请参阅 RFC 6125)。通常,您可以在X509Certificate您获得的(从 中获取链中的第一个对等证书)中查找主题备用名称SSLSession,否则,CN在主题专有名称中查找RDN。

2021-12-22T02:05:22   回复
IT小君

您可以通过附加获得对方的证书或者HandshakeCompletedListenerSSLSocket,或者通过获取和正从该事件的证书SSLSessionSSLSocket和获得从会话中同证书。

SSL 提供对等身份的隐私、完整性和身份验证。如果需要,应用程序应该检查该对等身份是否是应用程序期望的身份,以及该身份在应用程序中允许做什么。这是“授权”步骤,SSL 无法为您完成。

2021-12-22T02:05:22   回复
IT小君

AFAIK 证书验证应包括以下步骤:

  1. 证书形式验证通过验证其签名、当前时间的有效性和使用给定证书的域的有效性。无需任何额外的网络通信即可检查这些内容。
  2. 检查证书是否未被吊销 - 这是@Bruno 给出的答案中缺少的内容(否则我同意他的观点)。我认为只有在从签署证书的 CA(与 CA 的网络通信)获取新的 CRL(证书吊销列表)后才能进行此检查。
2021-12-22T02:05:23   回复
IT小君

您不必手动检查彼此的证书。

您只需将每个服务器证书导入彼此的 cacerts,这样两个应用程序服务器将自动相互信任。

2021-12-22T02:05:23   回复