【问题标题】:X.509 Certificate validation with Java and Bouncycastle使用 Java 和 Bouncycastle 进行 X.509 证书验证
【发布时间】:2011-01-28 07:19:22
【问题描述】:

通过bouncycastle wiki page,我能够了解如何创建 X.509 根证书和认证请求,但我不太了解之后如何明智地进行概念和编程。

让我们假设甲方提出一个证书请求并从 CA 获取他的客户端证书。 B 方如何验证 A 的证书? A需要什么样的证书?根证书? “普通”客户端证书?

如果我们假设 A 已经成功地将他的 DER 或 PEM 格式的证书发送给 B,那么验证在编程级别是如何工作的?

非常感谢任何帮助。

最好的问候, 抢

【问题讨论】:

    标签: java validation certificate bouncycastle x509


    【解决方案1】:

    好的,CAs背后的思路如下:

    • CA 是每个人都信任的人。为此,您的浏览器/电子邮件客户端/甚至我的手机上都提供了一系列受信任的 CA。在您的情况下,您的公共根密钥(证书)应该在您的应用程序中。
    • 用户向 CA 发送请求,以获取带有公钥的 PEM 格式的证书。 CA 对最终用户进行某种形式的验证(我故意留下这种模棱两可的含义),例如向他们收费或在增强验证(绿色)证书的情况下进行背景调查。
    • 如果 CA 认为用户的请求无效,他们会以某种方式传达此信息。
    • 如果这样做,他们会签署公钥并生成包含此信息的证书。这是您处理 cert-req 并将其转换为 X.509 证书的地方。
    • 其他用户遇到我们的虚构用户并想知道他们是否可以信任他们。因此,他们查看了证书,发现它是由他们信任列表中的某个人进行数字签名的。因此,他们信任根 CA 并且只有根 CA 可以签署(通过他们的私钥)该用户的公钥并且 CA 信任该用户,我们推断新用户可以信任虚构的 mr。

    在编程级别上,您可以通过阅读 X.509 证书并确定 CA 应该是谁来实现这一点。鉴于 CA 的指纹,您可以在数据库中找到它并验证签名。如果匹配,您就有了信任链。

    这行得通,因为正如我所说,只有 CA 可以创建数字签名,但任何人都可以验证它。这与加密概念正好相反。您所做的是“使用私钥加密”您希望签署的数据,并验证“使用公钥解密”是否等于您拥有的数据。

    【讨论】:

    • 感谢您对 CA 概念的详细解释。我现在明白了。我现在只需要弄清楚编程级别的细节。
    【解决方案2】:

    从程序员的角度来看,您需要做一些事情来验证 X.509 证书。

    1. 一组“信任锚”——您所依赖的 CA 的根证书。这些应该被保护不被篡改,这样攻击者就不会用他自己的假证书替换 CA 证书。这些证书中的公钥用于验证其他证书上的数字签名。
    2. 中间证书的集合。应用程序可能会保留这些证书的集合,但大多数使用证书的协议(如 SSL 和 S/MIME)都有提供额外证书的标准方法。存储这些不需要任何特别的照顾;它们的完整性受到根 CA 签名的保护。
    3. 吊销信息。即使证书是由 CA 颁发的,它也可能因为私钥被泄露,或者最终实体改变了他们的身份而被提前撤销。 (例如,一个人换了工作,其中包含其旧公司名称的证书被吊销。)CRL 或 OCSP 之类的网络服务可用于获取有关证书状态的更新。

    有了这些可用的输入,您可以使用built-in PKIX support 来构造和验证证书路径。

    /* Givens. */
    InputStream trustStoreInput = ...
    char[] password = ...
    List<X509Certificate> chain = ...
    Collection<X509CRL> crls = ...
    
    /* Construct a valid path. */
    KeyStore anchors = KeyStore.getInstance(KeyStore.getDefaultType());
    anchors.load(trustStoreInput, password);
    X509CertSelector target = new X509CertSelector();
    target.setCertificate(chain.get(0));
    PKIXBuilderParameters params = new PKIXBuilderParameters(anchors, target);
    CertStoreParameters intermediates = new CollectionCertStoreParameters(chain)
    params.addCertStore(CertStore.getInstance("Collection", intermediates));
    CertStoreParameters revoked = new CollectionCertStoreParameters(crls);
    params.addCertStore(CertStore.getInstance("Collection", revoked));
    CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
    /* 
     * If build() returns successfully, the certificate is valid. More details 
     * about the valid path can be obtained through the PKIXBuilderResult.
     * If no valid path can be found, a CertPathBuilderException is thrown.
     */
    PKIXBuilderResult r = (PKIXBuilderResult) builder.build(params);
    

    需要注意的重要一点是,如果找不到路径,您将无法获得有关原因的太多信息。这可能令人沮丧,但设计就是这样。一般来说,有许多潜在的路径。如果它们都因不同的原因而失败,路径构建器将如何决定报告的原因?

    【讨论】:

    • 感谢您的回答,但我应该说,我使用的是 Java ME,所以我必须依靠 bouncycastle-(lightweight)-API 来验证证书。您对此有什么想法,或者更好的是代码sn-p吗?非常感谢。
    • 这很清楚,但我无论如何都找不到从 XMLSignature 获取 List 链,即使在 xmldsig xml 文档中我可以看到所有证书
    • @jaime - 它们可以通过由KeyInfo 元素生成的X509Data 访问。我不熟悉 XML 签名支持,所以我不确定您如何从文档中生成此对象。
    • 进一步看,我可以看到你可以从XMLStructureunmarshalKeyInfo。它的content 将包括X509Data(如果存在)。
    • @erickson : 请看这个链接 - stackoverflow.com/questions/10411433/…
    猜你喜欢
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 2011-10-01
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多