Java中的SSL证书验证
假设我有两个我编写的Java应用程序:Java中的SSL证书验证,java,ssl,Java,Ssl,假设我有两个我编写的Java应用程序:Ping.jar和Pong.jar,它们部署并运行在两个独立的服务器上(Ping.jar部署到srv-01.myorg.com和Pong.jar部署到srv-02.myorg.com),这两个应用程序需要通过SSL相互通信(双向)。我们还假设每个应用程序都有自己的SSL证书 作为一名Java程序员,我如何编码Ping和Pong来验证彼此的SSL证书?每个CA是否都提供了某种我可以使用的RESTful API,比如说,HttpClient?Java有自己的证
Ping.jar
和Pong.jar
,它们部署并运行在两个独立的服务器上(Ping.jar
部署到srv-01.myorg.com
和Pong.jar
部署到srv-02.myorg.com
),这两个应用程序需要通过SSL相互通信(双向)。我们还假设每个应用程序都有自己的SSL证书
- 作为一名Java程序员,我如何编码
和Ping
来验证彼此的SSL证书?每个CA是否都提供了某种我可以使用的RESTful API,比如说,Pong
?Java有自己的证书验证API吗?我是否可以使用开源的第三方JAR或服务HttpClient
我很惊讶,当我在网上搜索这篇文章时,发现的东西很少。你不必手动检查彼此的证书
您只需将每个服务器证书导入到彼此的cacerts中,这样两个应用程序服务器就会自动相互信任。如果您使用Java SE SSL/TLS类(例如
SSLSocket
或SSLEngine
)进行连接,则使用
它将根据用于创建此SSLSocket
或SSLEngine
的SSLContext
验证远程方的证书
此SSLContext
将初始化,以指示应如何建立信任
除非您需要特定的配置,否则通常可以依赖:这将依赖PKIX算法(RFC 3280)根据一组信任锚(默认情况下在cacerts
中)验证证书keytool
显式添加证书
您还可以基于自定义密钥库以编程方式(如中所述)创建X509TrustManager
,并在不影响默认密钥库的特定SSLContext
中使用它
除此之外,如果您使用自己的协议,则需要验证您获得的证书是否与您要查找的主机名匹配(请参阅RFC 6125)。通常,您可以在获得的
X509Certificate
中查找主题备选名称(从SSLSession
中获取链中的第一个对等证书),否则,在受试者可分辨名称中查找CN
RDN。您可以通过在SSLSocket
上附加HandshakeCompletedListener
并从事件中获取证书来获取对等证书,或者从SSLSocket
获取SSLSession
并从会话获取对等证书
SSL提供了对等身份的隐私、完整性和身份验证。如有必要,应用程序应检查该对等身份是否是应用程序所期望的,以及该身份在应用程序中可以做什么。这是“授权”步骤,SSL无法为您完成 AFAIK证书验证应包括以下步骤:
您正在使用什么Web服务器?启用SSL(在您的例子中是相互SSL)通常是服务器配置的一种情况,而不是编码。好吧,让我们假设两种情况:(1)使用原始套接字/NIO的纯Java应用程序(正如我上面的用例所暗示的),以及(2)Oracle GlassFish。实际上,我现在对这两个用例都感兴趣。从未尝试过,这可能是一个地狱般的任务从头开始。公元2年。请查看,特别是关于SSL和客户端证书身份验证的两个问题。还有很多,所以请阅读Glassfish关于安全性的文档,但正如我所说的,这都是关于配置,而不是编码。如果两个端点都在撒谎呢?我提供了这个Ping/Pong示例来说明用纯Java验证证书的概念。事实上,我写乒乓球并不意味着他们可以互相信任!更抽象地思考:如果乒乓球和乒乓球是由不同的开发商店编写的,并且托管在两个完全不同的网络上,那么他们需要做什么来验证彼此的证书?是的,你需要这样做。SSL提供了对等身份的隐私、完整性和身份验证。如有必要,应用程序应检查该对等身份是否是应用程序所期望的,以及该身份在应用程序中可以做什么。这是“授权”步骤,SSL无法为您完成。这个答案是脆弱的(如果在生产中完成,则是危险的)。当任一终结点的证书被续订时,一切都将中断。此过程不包括检查证书是否被吊销。签名验证还不够,因为吊销的证书仍然具有有效的CA签名。