使用Java和Bouncycastle进行X.509证书验证

时间:2010-03-16 20:18:44

标签: java validation certificate bouncycastle x509

通过bouncycastle wiki page我能够理解如何创建X.509根证书和证书请求,但我不太明白如何在此之后继续进行概念和编程。

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

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

非常感谢任何帮助。

最诚挚的问候, 罗布

2 个答案:

答案 0 :(得分:31)

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

  1. 一组“信任锚” - 您依赖的CA的根证书。应该保护这些不被篡改,以便攻击者不会用他自己的假冒替换CA证书。这些证书中的公钥用于验证其他证书上的数字签名。
  2. 中级证书的集合。应用程序可能会保留这些集合,但使用证书的大多数协议(如SSL和S / MIME)都有标准方法来提供额外的证书。存储这些不需要特别小心;它们的完整性受根CA的签名保护。
  3. 撤销信息。即使证书是由CA颁发的,它也可能因为公开私钥而被提前撤销,或者最终实体更改了其身份。 (例如,一个人切换作业,并且其中旧公司名称的证书被撤销。)CRL或OCSP等网络服​​务可用于获取有关证书状态的更新。
  4. 如果这些输入可用,您可以使用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);
    

    需要注意的一件重要事情是,如果找不到路径,则无法获得有关原因的详细信息。这可能令人沮丧,但这是设计方式。一般来说,有许多潜在的途径。如果它们都因各种原因而失败,那么路径构建器将如何决定报告的原因?

答案 1 :(得分:9)

好的,CA背后的想法如下:

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

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

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