【问题标题】:SSL TrustStore without CA, only client certificateSSL TrustStore 没有 CA,只有客户端证书
【发布时间】:2020-03-19 13:40:25
【问题描述】:

我有一个自定义 CAroot.crt(由我生成),我所有的客户证书都使用这个 CAroot.crt 签名。我有一个 TrustStore.jks,我只放了客户端证书而不放 CAroot.crt,因为我希望可以随时从我的信任库中删除客户端。

当我尝试启动我的应用程序时,我得到了以下信息:

*** Certificate chain
<Empty>
***
main, fatal error: 42: null cert chain

这是我的 trustStore.jks:

Keystore type: jks
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: localhost
Creation date: Nov 23, 2019
Entry type: trustedCertEntry

Owner: CN=localhost, OU=IT, O=QUEROBUY, L=SAO CAETANO DO SUL, ST=SAO PAULO, C=BR
Issuer: CN=localhost, OU=IT, O=LANHELLAS XYZ, L=SAO CAETANO DO SUL, ST=SAO PAULO, C=BR
Serial number: 5416c04e360f9d50323c52d8a5b04be2969c9b86
Valid from: Sat Nov 23 16:39:54 BRT 2019 until: Tue Apr 06 16:39:54 BRT 2021
Certificate fingerprints:
     MD5:  8F:29:1C:1F:05:89:0B:E6:A0:57:84:FE:B0:78:68:2D
     SHA1: 95:C8:EA:0E:C8:7C:4E:99:E4:73:85:49:57:D6:BB:88:AF:52:52:12
     SHA256: 7E:ED:19:AF:02:DB:CC:88:98:D0:10:4E:39:67:AA:4D:3F:70:DA:76:03:1B:CB:41:06:DC:3B:51:38:16:78:5F
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 1


*******************************************
*******************************************

如果我将“CARoot.crt”添加到我的 trustStore.jks 一切正常,但我失去了使某些特定客户端证书无效的机会。想象一下,我有 10 个客户端,每个客户端都有您自己的证书 (.crt),由“CARoot.crt”分配,但由于某种原因,客户端 001 应该立即失效,我只会从服务器中的 trustStore.jks 中删除您的公钥,而不我应该等待证书到期日期。

【问题讨论】:

    标签: ssl openssl ssl-certificate x509certificate2


    【解决方案1】:

    为什么:如果您稍早查看调试日志,您会看到 CertificateRequest 消息,其中指定(除其他外)服务器要求的 Cert[ificate] 权限;见rfc5246。 Java 将其定义为信任库中证书的主题名称,因为通常期望信任库中的证书是 CA 证书(通常是 CA root 证书,就像预定义的证书一样)。大多数客户端软件都遵循此指令,但也有例外。因此,如果您的信任库包含类似

    的证书
    Subject=Client1 Issuer=MyCA
    Subject=Client2 Issuer=MyCA
    Subject=Client3 Issuer=MyCA
    

    那么您的服务器将要求任何Client1 Client2 Client3不是 MyCA 颁发的证书。如果客户端实际上只有一个证书并且它是 for 例如Client2 MyCA 颁发——不是任何Clientn——大多数客户端软件会认为此服务器/握手不可接受该证书。

    PKI 方式。证书不能在到期前失效是不正确的。 PKI 通常明确设计用于处理此类情况,通常称为撤销。证书在到期前被吊销的原因有很多;对于用于 SSL/TLS 的特定 PKI 方案(以及 Java 用于其他事情,如代码签名),即 PKIX(或有效等效的 X.509),请参阅rfc5280 5.3.1 以及第 5 节的其余部分以获取证书吊销列表 (CRL),旧的和传统的处理吊销的方式,rfc6960 用于在线证书状态协议 (OCSP),这是较新的方式。

    对于“真正的”(公共)PKI,这主要是可行的。 Java 实现了 PKIX 撤销检查,但对于 SSL/TLS (JSSE),它默认禁用;您必须设置 sysprop com.sun.net.ssl.checkRevocation 才能使用它。您可能还需要为 CRL 设置 com.sun.security.enableCRLDP,而 AFAICT 始终需要为 OCSP 设置 security 属性(不是 sysprop)ocsp.enable。参见例如:
    Check X509 certificate revocation status in Spring-Security before authenticating
    Checking a X509 Certificate Revocation
    Java SSL Certificate Revocation Checking

    但是运行 CRL 分发点和/或 OCSP 响应程序以便它们正确并且在需要时可用 - 可以是任何时间 - 并非易事;这是真正的 CA 收费(或获得补贴)的事情之一。为您自己的个人 CA 执行此操作可能会很痛苦,也可能实际上是不可能的,但如果您愿意,请更具体地了解您的 CA。

    您的情况原则上更简单;您只有一个 CA 并且您操作它,因此您知道何时发生撤销。当它(它们)更改时,您可以轻松地将 CRL 提供给服务器。但是 AFAICS 内置代码无法使用该信息,因此您必须使用允许编写自己的 TrustManager 代替内置代码的钩子,并将其修改为使用验证器使用 CRL 的 CertStore。这可能也是一项相当多的工作,但只有一次。

    解决方法。您可以继续使用通过修改服务器或客户端来单独信任叶证书的方法,而不是在 PKI 术语中“正确”地执行此操作。

    您可以更改服务器中的 (X509)TrustManager 挂钩以照常验证证书,但覆盖 getAcceptedIssuers 以返回不同的(并且根据您的情况更正)“请求的”CA 列表,从而导致 JSSE 发送 CertificateRequest这会导致客户端使用正确的证书。

    根据客户端的不同,您可以将它们更改为忽略“请求”的 CA 并发送他们的证书——服务器的默认 TrustManager 将验证它是否在信任库中( CA 是)。对于 OpenSSL,这很容易; OpenSSL 已经忽略了请求的 CA 列表,只发送配置的任何内容。对于 Java,您可以挂钩客户端 KeyManager 并覆盖 chooseClientAliases 方法,以不像通常那样检查所需的颁发者列表。对于其他客户,请添加到您的 Q 或询问新的。

    【讨论】:

    • 感谢 dave,我知道这不是一个简单的方法(没有钩子)直接在trustedStore 中使用证书列表而不需要root ca。
    • 我会阅读更多关于 OCSP 的新方法,对我来说似乎很好
    【解决方案2】:

    TrustStore.jks 是 java 将如何确定它是否信任证书的方式。它本质上是一个根证书的密钥库文件。如果您想避免“不信任消息”,则必须将您的根证书添加到此存储中。

    在您的场景中,由于您使用该根来颁发 10 个客户端证书,因此从您的信任或密钥存储中删除 client_certificate.crt 不会不信任它。因为,按照设计,java 正在查看 TrustStore 并找到根证书,因此仍然信任 client_certificate.crt。您将需要重新设计您的 CA。

    部署任何类型的 PKI 基础架构时,您还需要设置 CRL 和/或 OCSP 服务器。这是用于撤销证书的两种协议。

    我还建议您不要直接从根颁发“最终用户证书”。它最好在根目录下颁发中间证书,然后使用 middle_certificate.crt 来颁发您的实际服务器或客户端证书。 原因请参见此处:https://security.stackexchange.com/questions/128779/why-is-it-more-secure-to-use-intermediate-ca-certificates#128800

    这是一种使用 OpenSSL 部署您自己的 CA 的简便方法。它将向您展示如何设置根服务器、中间服务器和撤销服务器。 https://jamielinux.com/docs/openssl-certificate-authority/

    【讨论】:

    • 虽然 CRL 和/或 OCSP 通常是 PKIX 答案,但默认情况下 Java SSL/TLS 会禁用它们;看我的回答。
    • 谢谢你的回答,我会考虑我的CA策略
    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 2016-01-18
    • 2022-08-22
    • 2013-10-08
    • 1970-01-01
    相关资源
    最近更新 更多