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

发布于 2024-08-25 23:28:26 字数 386 浏览 8 评论 0原文

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

假设 A 方发出证书请求并从 CA 获取其客户端证书。 B 方如何验证 A 的证书? A需要什么样的证书?根证书? “普通”客户端证书?

如果我们假设 A 已成功将其 DER 或 PEM 格式的证书发送给 B,那么编程级别的验证如何进行?

非常感谢任何帮助。

此致, 抢

through the bouncycastle wiki page I was able to understand how to create a X.509 root certificate and a certification request, but I do not quite understand how to proceed concept- and programming wise after that.

Lets assume party A does a cert request and gets his client certificate from the CA. How can some party B validate A's certificate? What kind of certificate does A need? A root certificate? A 'normal' client certificate?

And how does the validation work on programming level, if we assume that A has successfully send his certificate in DER or PEM format to B?

Any help is much appreciated.

Best Regards,
Rob

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

会发光的星星闪亮亮i 2024-09-01 23:28:26

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

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

有了这些可用的输入,您就可以使用 内置 -在 PKIX 支持中构建和验证证书路径。

/* 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);

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

From a programmer's perspective, you need a few things to validate an X.509 certificate.

  1. A set of "trust anchors"—the root certificates of CAs that you rely on. These should be protected from tampering, so that an attacker doesn't replace a CA certificate with his own fake. The public keys in these certificates are used to verify the digital signatures on other certificates.
  2. A collection of Intermediate certificates. The application might keep a collection of these, but most protocols, like SSL and S/MIME, that use certificates have a standard way to provide extra certificates. Storing these doesn't require any special care; their integrity is protected by the signature of a root CA.
  3. Revocation information. Even if a certificate was issued by a CA, it might have been revoked prematurely because the private key was disclosed, or the end entity changed their identity. (For example, a person switches jobs and a certificate with their old company's name in it is revoked.) CRLs or a web-service like OCSP can be used to get an update about the status of a certificate.

With these inputs available, you can use the built-in PKIX support to construct and validate a certificate path.

/* 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);

An important thing to note is that if a path cannot be found, you don't get much information about the reason. This can be frustrating, but it is that way by design. In general, there are many potential paths. If they all fail for different reasons, how would the path builder decide what to report as the reason?

梦途 2024-09-01 23:28:26

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

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

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

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

Ok, the idea behind CAs is as follows:

  • CAs are people everyone trusts. To this end, a selection of Trusted CAs is available in your browser/email client/even on my mobile. In your case, your public root key (certificate) should be in your application.
  • Users send requests to the CA for a certificate in PEM format with the public key. CAs do some (I leave this ambiguous deliberately) form of verification of the end user, such as charging them money or in the case of enhanced verification (green) certs, background checks.
  • If the CA doesn't think the user's request is valid, they communicate this somehow.
  • If they do, they sign the public key and produce a certificate containing this information. This is where you process the cert-req and turn it into an X.509 cert.
  • Other users come across our fictitious user and want to know if they can trust them. So, they take a look at the certificate and find it is digitally signed by someone they have in their trust list. So, the fact that they trust the root CA and only the root CA could sign (via their private key) this user's public key and the CA trusts the user, we deduce that the new user can trust mr fictitious.

On a programmatic level, you implement this by reading the X.509 certificate and working out who the CA is supposed to be. Given that CA's fingerprint, you find it in your database and verify the signature. If it matches, you have your chain of trust.

This works because, as I've said, only the CA can create the digital signature but anyone can verify it. It is exactly the reverse of the encryption concept. What you do is "encrypt with the private key" the data you wish to sign and verify that the "decrypt with the public key" equals the data you've got.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文