我有一个CRL和一个作为CA证书的自签名证书。我需要验证相同的CA是否已在Java中发布了CRL和根证书。我想到的方式是:
X500Principal rootCertIssuer = rootCertificate.getIssuerX500Principal();
X500Principal crlIssuer = crl.getIssuerX500Principal();
if(rootCertIssuer.getName().equals(crlIssuer.getName()))
System.out.println("Issuer same!");
else
System.out.println("Issuer different!");
这似乎不对,因为如果CRL或根证书之一中缺少国家/州信息,equals()
将返回false
。我该怎么办?或者,与我的想法相反,这种方法是对的吗?
谢谢!
答案 0 :(得分:1)
正如@frasertweedale所提到的,证书颁发者和CRL发行者不一定需要是相同的。但是,没有太多理由将CRL颁发委托给另一个机构,并非所有系统都支持这一点。例如,Windows链验证代码仅支持由颁发CRL涵盖的证书的同一CA颁发(由其签名)的CRL。
通常,验证逻辑由两部分组成,如下所示:
CRLDistributionPoints
序列。如果存在具有呈现cRLIssuer
结构的条目,则此分发点引用的CRL由cRLIssuer
字段中指定的实体签名。如果未显示cRLIssuer
字段,则证书和CRL由同一CA签名,并在distributionPointName
字段中指定CRL位置。针对发行人的CRL验证分两步执行:
Issuer
和CRL颁发者证书的Subject
字段进行二进制(非字符串)比较。如果比较失败,则CRL无效。有关CRL分发点扩展组成和处理规则的更多信息:RFC 5280 §4.2.1.13
答案 1 :(得分:1)
注意,由于Java8有一种验证证书链的方法,包括CRL检查,请参见此处:Java SSL Certificate Revocation Checking。
如果您使用自签名证书,您确实需要确保正确填充相关方的密钥/信任存储(默认cacerts)。
我认为,问题名称的字符串比较是一种非常弱的方法。
答案 2 :(得分:0)
如果CA证书和CRL上的发行人专有名称不同,则必须将其视为由不同的发行人签发。如果发行人DN"的位丢失"在生成CRL或任何其他签名对象时,这违反了X.509和错误。
请注意,CA可以委派 CRL签名到下级CRL颁发者,因此通用 CRL验证函数必须处理此案例,以及直接CRL颁发。< / p>