Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何检查X509证书是否为CA证书?_Java_Certificate_X509certificate_Ca - Fatal编程技术网

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

Java 如何检查X509证书是否为CA证书?,java,certificate,x509certificate,ca,Java,Certificate,X509certificate,Ca,我有一个Java中的X509Certificate实例,我需要确定它是CA证书还是用户证书 有人能提供帮助吗 提前谢谢 根CA将是启用了keyCertSign标志的自签名证书。在大多数情况下,为了方便起见,通用名称可能包括单词CA。中间CA证书可以由根CA(或另一中间!)签名。您的brower密钥存储将有常用的可信CA证书示例 从 根据我所做的研究,可以通过检查基本约束来检查它! 检查返回的getBasicConstraints()方法的结果 因此,如果该方法返回结果!=-1,可以将证书视为CA

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

有人能提供帮助吗


提前谢谢

根CA将是启用了
keyCertSign
标志的自签名证书。在大多数情况下,为了方便起见,通用名称可能包括单词
CA
。中间
CA
证书可以由
根CA
(或另一中间!)签名。您的brower密钥存储将有常用的可信CA证书示例


根据我所做的研究,可以通过检查基本约束来检查它! 检查返回的
getBasicConstraints()
方法的结果

因此,如果该方法返回结果
!=-1
,可以将证书视为
CA证书

我已经用几个
CA证书
(根证书和中间证书)对此进行了检查,它的工作原理如所述。
我还用几个用户证书检查了这个方法,结果该方法返回-1。

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
}

哦,看看slims对Java中如何操作的回答!互操作性和标准的窗口!根据您的应用程序,您只需拨打电话,即猜测CA、客户端或提供某种机制让用户决定。每种情况都是危险的。你可能陷入了一个艰难的境地,在那里你需要平衡可用性和安全性。对严格和它的工作,太松懈和它的安全漏洞。您可能需要假设用户证书链必须由一组允许的根CA(例如JVM中包含的根CA)之一签名。我认为你必须提供选择,并迫使你的主管做出决定。你问了几个问题,这些问题已经得到了回答。你应该将答案标记为已接受,以回馈社区。对不起,我刚刚意识到该怎么做。谢谢你指点我接受答案。我想我在Android上发现了一个例外。在大多数API版本(大于API 15)上,它的工作原理如所述,但在API17上,它将返回
!=-1
在CA和用户证书上。仅在API17或API17+上?我没有参与Android的开发,所以我没有在不同的API版本上尝试过。只有在API 17上。我最终使用了双重检查-首先
getBasicConstraints()-1
以及之后的
证书。getKeyUsage()[5]==true
。我对Oracle文档的阅读使我认为这是可能的,到目前为止,我还没有发现这种方法的错误。这里是文档的链接。Java 7没有对此功能进行更改。是否有某种方法可以让我们也识别出哪个CA(名称本身)实际签署了证书?我想,检查发行人名称可能是一种方法,但我想这可能不太可靠。我最后检查了
!certificate.getKeyUsage()[5]
参考@dpinyaOne的答案可能需要检查
keyUsage
数组是否为null,因为如果此证书不包含keyUsage扩展名,则
返回null。
密钥用法与基本构造函数CA:true不同。您可以拥有CA:true证书,而不设置任何密钥用法。根据RFC 5280中的“4.2.1.3.密钥用法”一节:“合格CA必须在包含公钥的证书中包含此扩展,该公钥用于验证其他公钥证书或CRL上的数字签名。当存在时,合格CA应将此扩展标记为关键”. 您可以拥有一个不使用密钥的CA,但不能拥有一致的CA。
X509Certificate cert = ...;
boolean[] keyUsage = cert.getKeyUsage();
if ( keyUsage[5] ) {
    // CA certificate
}
else {
    // User certificate
}