Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的SSL证书验证_Java_Ssl - Fatal编程技术网

Java中的SSL证书验证

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有自己的证

假设我有两个我编写的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有自己的证书验证API吗?我是否可以使用开源的第三方JAR或服务

我很惊讶,当我在网上搜索这篇文章时,发现的东西很少。

你不必手动检查彼此的证书


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

如果您使用Java SE SSL/TLS类(例如
SSLSocket
SSLEngine
)进行连接,则使用

它将根据用于创建此
SSLSocket
SSLEngine
SSLContext
验证远程方的证书

SSLContext
将初始化,以指示应如何建立信任

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

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


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

您可以通过在
SSLSocket
上附加
HandshakeCompletedListener
并从事件中获取证书来获取对等证书,或者从
SSLSocket
获取
SSLSession
并从会话获取对等证书


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

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

  • 通过验证其签名、当前时间的有效性和使用给定证书的域的有效性,对证书进行正式验证。无需任何额外的网络通信即可检查这些内容
  • 检查证书是否未被吊销-这是@Bruno给出的答案中缺少的内容(否则我同意他的说法)。我认为只有在从签署证书(与CA的网络通信)的CA获得新的CRL(证书吊销列表)后才能执行此检查

  • 您正在使用什么Web服务器?启用SSL(在您的例子中是相互SSL)通常是服务器配置的一种情况,而不是编码。好吧,让我们假设两种情况:(1)使用原始套接字/NIO的纯Java应用程序(正如我上面的用例所暗示的),以及(2)Oracle GlassFish。实际上,我现在对这两个用例都感兴趣。从未尝试过,这可能是一个地狱般的任务从头开始。公元2年。请查看,特别是关于SSL和客户端证书身份验证的两个问题。还有很多,所以请阅读Glassfish关于安全性的文档,但正如我所说的,这都是关于配置,而不是编码。如果两个端点都在撒谎呢?我提供了这个Ping/Pong示例来说明用纯Java验证证书的概念。事实上,我写乒乓球并不意味着他们可以互相信任!更抽象地思考:如果乒乓球和乒乓球是由不同的开发商店编写的,并且托管在两个完全不同的网络上,那么他们需要做什么来验证彼此的证书?是的,你需要这样做。SSL提供了对等身份的隐私、完整性和身份验证。如有必要,应用程序应检查该对等身份是否是应用程序所期望的,以及该身份在应用程序中可以做什么。这是“授权”步骤,SSL无法为您完成。这个答案是脆弱的(如果在生产中完成,则是危险的)。当任一终结点的证书被续订时,一切都将中断。此过程不包括检查证书是否被吊销。签名验证还不够,因为吊销的证书仍然具有有效的CA签名。