如何检查X509证书是否为CA证书?

18

我在Java中有一个X509Certificate实例,需要确定它是CA证书还是用户证书。

有人可以提供帮助吗?

先谢谢了!


您已经提出了几个问题并得到了回答。您应该将这些答案标记为已接受,以回馈社区。 - James Sheppard
抱歉,我刚刚意识到该怎么做了。感谢您指引我接受答案。 - Jurica Krizanic
3个回答

18

根据我进行的研究,可以通过检查基本约束来进行检查!请查看API以返回getBasicConstraints()方法的结果。

因此,如果该方法返回结果不等于-1,则可以将证书视为CA证书

我已经使用几个CA证书(根和中间)进行了检查,结果与描述相符。我还使用几个用户证书进行了此方法的检查,该方法返回结果为-1。


1
我认为我在Android上发现了这个规则的一个例外。在大多数API版本(大于API 15)上,它按照描述的方式工作,但在API17上,它会在CA和用户证书上都返回!= -1 - JFreeman
只在API17上还是在API17及以上版本上?我没有参与Android开发,所以我没有在不同的API版本上尝试过这个。 - Jurica Krizanic
仅适用于API 17。我最终使用了双重检查-首先是getBasicConstraints()!= -1,然后是certificate.getKeyUsage()[5] == true。我阅读Oracle文档时认为这是可能的,并且到目前为止我没有发现这种方法的错误。这里是文档链接X509Certificate Java6。Java 7对此功能没有引入更改。 - JFreeman
有没有办法可以识别出签署证书的CA机构的名称呢?检查颁发者名称可能是一种方法,但我想那可能不太可靠。 - qre0ct
最终我检查了!certificate.getKeyUsage()[5]。参考@dpinya的答案。 - JFreeman

13

X509Certificate.getKeyUsage() javadoc:

获取一个布尔数组,表示KeyUsage扩展的位(OID = 2.5.29.15)。密钥用途扩展定义了证书中包含的密钥的用途(例如,加密、签名、证书签名)。此项的ASN.1定义为:

          KeyUsage ::= BIT STRING {
              digitalSignature        (0),
              nonRepudiation          (1),
              keyEncipherment         (2),
              dataEncipherment        (3),
              keyAgreement            (4),
              keyCertSign             (5),  --> true ONLY for CAs
              cRLSign                 (6),
              encipherOnly            (7),
              decipherOnly            (8) }
证书可以按以下方式检查:
X509Certificate cert = ...;
boolean[] keyUsage = cert.getKeyUsage();
if ( keyUsage[5] ) {
    // CA certificate
}
else {
    // User certificate
}

可能需要检查keyUsage数组是否为空,因为如果此证书不包含KeyUsage扩展,则返回null。 - sedovav
关键用途不等同于基本约束 CA: true。你可以拥有一个 CA:true 的证书,而没有设置任何关键用途。 - Alex G
根据RFC 5280,第4.2.1.3节“密钥用途”,符合标准的CA必须在包含用于验证其他公钥证书或CRL上的数字签名的公钥的证书中包括此扩展。当存在时,符合标准的CA应将此扩展标记为关键。您可以拥有没有密钥用途的CA,但不能拥有符合标准的CA。 - dpinya

2

根证书(Root CA)是一种启用了keyCertSign标志的自签名证书。在大多数情况下,为方便起见,通用名称中可能包含单词CA。中间CA证书可以由Root CA(或另一个中间机构!)签名。您的浏览器密钥库将包含常用可信CA证书的示例。

摘自互联网工程任务组

The keyCertSign bit is asserted when the subject public key is
    used for verifying a signature on certificates.  This bit may only
    be asserted in CA certificates.

哦,还要看一下Slim的Java实现方法! - Anthony Palmer
互操作性和标准不再是问题!根据您的应用程序,您只需进行调用,即猜测CA、客户端或提供某种机制让用户决定。这些场景都很危险。您可能会陷入一个艰难的境地,需要平衡易用性与安全性。如果太严格,它就不能正常工作;如果太松散,它就成为了安全漏洞。您可能需要假设用户证书链必须由一组允许的根CA之一签名(例如,在JVM中包含的那些)。我认为,您需要提供选项并强制您的主管做出决定。 - Anthony Palmer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接