有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

信任服务器上所有客户端证书的ssl安全含义(Java X509TrustManager)

在本网站和其他网站上,通常建议使用自定义的“空”X509TrustManager实现(即信任所有证书的实现,例如此答案:https://stackoverflow.com/a/54358567或此答案中的“选项2:https://stackoverflow.com/a/2893932)。人们(正确地)批评这是不安全和危险的建议。这通常用于客户端信任任何服务器证书

我想知道,对于信任任何客户端证书的服务器而言,这种做法是否一定是不安全的(假设所述证书随后根据受信任证书列表单独检查)

上下文:我正在尝试创建一个基本的Gemini服务器(https://gemini.circumlunar.space/docs/specification.gmi)。提供的大多数页面都不需要客户端证书,但如果客户端提供随机证书,我不希望TLS握手失败。某些页面(例如,管理员的日志查看器)可能需要特定的客户端证书(例如,使用存储在服务器上硬编码文件路径的公钥)。其他页面可能希望信任证书的动态列表(例如,来自注册用户数据库)

如果我创建一个信任所有客户端证书的自定义X509TrustManager,并在我的SSLServerSocketFactory中使用它:

  1. clientSocket.getSession().getPeerCertificates()返回的证书是否仍然根据其私钥进行了预验证(即,如果有人出示了管理员证书,但没有私钥,getPeerCertificates()是否会返回空数组)
  2. 将我的TrustManager中的checkServerTrusted()/getAcceptedIssuers()方法保留为空/null是否存在任何风险?如果这个TrustManager只由我的服务器socket工厂使用,这些方法会被调用吗
  3. 有没有更好的方法来实现我的目标

共 (1) 个答案

  1. # 1 楼答案

    I want to know if this practice is necessarily unsafe for a server trusting any client certificate (assuming said certificate is then checked separately against a list of trusted certs).

    与最初不请求客户端证书相比,请求但不验证客户端证书不会带来任何安全问题

    使用客户端证书进行身份验证而不进行验证显然会增加问题,因为在这种情况下,攻击者可能会提供自制的证书。但是正如您所写的,稍后在接受is进行身份验证之前,客户机证书将在TLS握手之外进行检查(希望正确)。在这种情况下,不在握手时检查是完全安全的

    I want to know if this practice is necessarily unsafe for a server trusting any client certificate (assuming said certificate is then checked separately against a list of trusted certs).

    即使证书验证已关闭,仍将验证客户端是否拥有提供的证书,即它是否具有匹配的私钥

    Is there any risk to also leaving the checkServerTrusted()/getAcceptedIssuers() methods in my TrustManager blank/null? If this TrustManager is only used by my server socket factory, will these methods ever be called?

    checkServerTrusted将被调用以检查服务器证书,即仅在客户端。所以这个函数并不重要。 我不确定getAcceptedIssuers——可能是在将接受的CA列表发送给客户端时调用它。不过,这个列表是否为空并不重要