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

使用Java和Bouncycastle进行X.509证书验证,java,validation,certificate,bouncycastle,x509,Java,Validation,Certificate,Bouncycastle,X509,通过,我能够理解如何创建一个X.509根证书和一个证书请求,但我不太理解如何继续这个概念——以及之后的编程 假设甲方发出证书请求并从CA处获得其客户证书。乙方如何验证甲方的证书?A需要什么样的证书?根证书?“正常”客户端证书 如果我们假设A已经成功地将DER或PEM格式的证书发送给B,那么验证在编程级别上是如何工作的 非常感谢您的帮助 致以最良好的祝愿, Rob好的,CAs背后的理念如下: CAs是每个人都信任的人。为此,您的浏览器/电子邮件客户端/甚至在我的手机上都可以选择受信任的CA。在您

通过,我能够理解如何创建一个X.509根证书和一个证书请求,但我不太理解如何继续这个概念——以及之后的编程

假设甲方发出证书请求并从CA处获得其客户证书。乙方如何验证甲方的证书?A需要什么样的证书?根证书?“正常”客户端证书

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

非常感谢您的帮助

致以最良好的祝愿,
Rob

好的,CAs背后的理念如下:

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


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

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

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

    /* 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);
    
    /*吉文斯*/
    InputStream trustStoreInput=。。。
    字符[]密码=。。。
    列表链=。。。
    集合crls=。。。
    /*构造一个有效路径*/
    KeyStore anchors=KeyStore.getInstance(KeyStore.getDefaultType());
    加载(trustStoreInput,密码);
    X509CertSelector目标=新的X509CertSelector();
    target.setCertificate(chain.get(0));
    PKIXBuilderParameters params=新的PKIXBuilderParameters(锚,目标);
    CertStoreParameters中间产品=新集合CertStoreParameters(链)
    params.addCertStore(CertStore.getInstance(“Collection”,intermediates));
    CertStoreParameters Reversed=新集合CertStoreParameters(CRL);
    params.addCertStore(CertStore.getInstance(“Collection”,已撤销));
    CertPathBuilder=CertPathBuilder.getInstance(“PKIX”);
    /* 
    *如果build()成功返回,则证书有效。更多细节
    *关于有效路径,可通过PKIXBuilderResult获取。
    *如果找不到有效路径,将引发CertPathBuilderException。
    */
    PKIXBuilderResult r=(PKIXBuilderResult)builder.build(params);
    

    需要注意的一点是,如果找不到路径,您将无法获得有关原因的更多信息。这可能令人沮丧,但这是设计的方式。一般来说,有许多潜在的途径。如果它们都因不同的原因失败,路径生成器将如何决定报告什么作为原因?

    感谢您对CA概念的详细解释。我现在明白了。我现在只需要弄清楚编程级别的细节。谢谢你的回答,但我应该说,我使用的是Java ME,所以我必须依靠bouncycastle-(轻量级)-API来验证证书。您对此有什么想法,或者更好的是有一段代码片段吗?非常感谢。这非常清楚,但我无论如何都找不到从XMLSignature获取列表链的方法,即使在xmldsig xml文档中我可以看到所有certificates@jaime-可通过从
    KeyInfo
    元素生成的。我不熟悉XML签名支持,因此我不确定如何从文档生成此对象。进一步查看,我可以看到您可以从
    XMLStructure
    生成
    KeyInfo
    。Its将包括
    X509数据