Java中的SSL证书validation
假设我有两个我写的Java应用程序: Ping.jar
和Pong.jar
,它们被部署并在两个独立的服务器上运行( Ping.jar
部署到srv-01.myorg.com
, Pong.jar
部署到srv-02.myorg.com
),这两个应用程序需要通过SSL相互通信(双向)。 我们还假设每个应用程序都有自己的SSL证书。
- 作为Java程序员,我如何编写
Ping
和Pong
代码以validation彼此的SSL证书? 每个CA都提供某种RESTful API,我可以使用HttpClient
吗? Java是否有自己的证书validationAPI? 是否有我可以使用的开源第三方JAR或服务?
当我在网上搜索这个时,我感到很惊讶。
如果您使用Java SE SSL / TLS类(例如SSLSocket
或SSLEngine
)进行连接,那么您将使用Java安全套接字扩展(JSSE) 。
它将根据用于创建此SSLSocket
或SSLEngine
的SSLContext
validation远程方的证书。
此SSLContext
将使用TrustManager
进行初始化,以确定应如何建立信任。
除非您需要特定配置,否则通常可以依赖于默认值 :这将依赖于PKIX算法(RFC 3280)来针对一组信任锚(默认情况下在cacerts
)validation证书。 Oracle JRE附带的cacerts
是一个JKS密钥库,您可以向其添加其他证书。 例如,您可以使用keytool
显式添加证书。
您还可以通过编程方式(如本答案中所述 )基于自定义密钥库创建X509TrustManager
,并在不影响默认密钥库的特定SSLContext
中使用它。
除此之外,如果您使用自己的协议,则需要validation您获得的证书是否与您要查找的主机名相匹配(请参阅RFC 6125)。 通常,您可以在X509Certificate
查找主题备用名称(从SSLSession
获取链中的第一个对等证书),如果失败,请在主题专有名称中查找CN
RDN。
您可以通过将HandshakeCompletedListener
附加到SSLSocket
并从事件中获取证书,或者通过从SSLSocket
获取SSLSession
并从会话中获取对等证书来获取对等证书。
SSL提供对等身份的隐私,完整性和身份validation。 应用程序是否必要时应检查该对等标识是否是应用程序所期望的标识以及该标识允许在应用程序中执行的操作。 这是“授权”步骤,SSL无法为您执行此操作。
您不必手动检查彼此的证书。
您只需将每个服务器证书导入到彼此的cacerts中,这样两个应用程序服务器就会自动相互信任。