查找证书是自签名的还是 CA 签名的

Posted

技术标签:

【中文标题】查找证书是自签名的还是 CA 签名的【英文标题】:Find if a certificate is self signed or CA signed 【发布时间】:2012-05-05 17:43:33 【问题描述】:

我有一个网络应用程序,它允许用户上传 pkcs12。我将 pkcs12 作为二进制文件存储在数据库中。有什么方法可以让我知道 pkcs12 中的证书是自签名的还是 CA 签名的?

我在 tomcat 上运行一个 Java Web 应用程序,并且可以使用 openssl。

【问题讨论】:

在安全 stackexchange 上查看我的 answer。 【参考方案1】:

编辑:今天这个问题有两个更好的答案:

https://***.com/a/57927684/377270 https://***.com/a/14515875/377270

但是,我认为还有一些更重要的问题需要解决——为什么人们想了解自签名证书。目标是什么?正在解决什么问题?可能试图将证书分成两堆,自签名和非自签名,对于大多数情况来说是错误的方法。几乎可以肯定,更好的方法是验证任何给定证书是否具有来自受信任证书颁发机构的有效签名链,以及与给定证书关联的任何连接是否与证书匹配。

这是我原始答案的其余部分。这可能不是你想要的。


这有点hacky,但是openssl x509 命令可以同时报告颁发者和主题。如果主题和发行者相同,则为自签名;如果它们不同,那么它是由 CA 签署的。 (严格来说,很多自签名证书由 CA 签名——他们自己。)

在测试这个理论时,我进行了一些测试;它运行类似:

cd /etc/ssl/certs
for f in *.0 ; do openssl x509 -in $f -issuer | head -1 > /tmp/$f.issuer ; openssl x509 -in $f -subject | head -1 > /tmp/$f.subject ; done
 cd /tmp
 sed -i -e s/issuer=// *.issuer
 sed -i -e s/subject=// *.subject
 cd /etc/ssl/certs/
 for f in *.0 ; do diff -u /tmp/$f.issuer /tmp/$f.subject ; done

希望这会有所帮助。

【讨论】:

您可以通过执行openssl x509 -in $f -issuer -subject 并删除head 和第二个openssl 命令来改进这一点。 您说“如果它们不同,那么它是由 CA 签名的”。我认为重要的是要注意它实际上并没有。通常,证书由多个证书链签名。例如:您的主证书由第二个证书签名,而不是由另一个证书签名,依此类推。检查链中的所有证书以确保第一个证书验证非常重要。否则,这是一项很棒的技术。谢谢! "-noout" 会比 "| head -1" 干净一点 如果有人创建了一个将“颁发者”字段设置为某个已知 CA 的证书,然后用他自己的私钥对其进行签名怎么办?这似乎不是识别自签名证书的正确防弹方法。您应该检查签名是否来自与证书本身相同的密钥。 “为什么要了解自签名证书”。在大型商店中,您将需要扫描已知设备以了解证书的数量、类型、健康状况和到期时间。如果您的政策是在商店中没有自签名证书,但您知道,这种情况发生了,您可能需要专门标记这些。【参考方案2】:

这里接受的答案并不完全正确。老问题,但这是谷歌“如何判断证书是否为自签名”的第一个结果,因此需要清除。

如果颁发者和主题匹配,证书几乎总是自签名的,但不能保证。证书可以是“自行颁发”的,它具有相同的颁发者/主题,但由未与证书中的公钥配对的私钥签名。

上面来自 NitinB 的答案的第一部分是检查自签名证书的正确方法:

openssl verify -CAfile self_signed_cert.pem self_signed_cert.pem

“所有自签名证书都是自签发的,但并非所有自签发证书都是自签发的。”

引用:https://www.rfc-editor.org/rfc/rfc5280

“自签发证书是颁发者和主体是同一实体的 CA 证书。生成自签发证书以支持策略或操作的更改。自签发证书是自签发证书,其中数字签名可以由绑定到证书中的公钥进行验证。”

【讨论】:

【参考方案3】:

Java 无法分析 PKCS12,因此您必须使用 openssl 将其转换为 keystore

这里的keystore既有私钥又有X509证书(或者你可以选择只存储证书)。然后使用标准 JAVA API 从keystore 获取颁发者并手动验证颁发者。

【讨论】:

这是错误的。 Java 至少从 2006 年的 j6 开始处理 PKCS12 密钥库(至少包括私钥),尽管 commandline keytool 默认情况下 仅在 8u60 之后才这样做,这是在 2015 年这个答案之后. openssl 只能将 pkcs12 转换为 CERTIFICATE(s) 和 PRIVATE KEY 的单独 PEM 对象,但 Java 不能将其中任何一个用作密钥库——尽管它只能将前者导入到密钥库并使用它。【参考方案4】:

以下电子邮件线程准确地告诉了验证 base64 编码证书(即 PEM)是否是自签名的正确方法:http://marc.info/?l=openssl-users&m=116177485311662&w=4

下面是sn-p的代码:

openssl verify -CAfile self_signed_cert.pem self_signed_cert.pem

应该返回:

self_signed_cert.pem: OK

或者比较发行者和主题。如果它们相同,则为自签名

openssl x509 -in cert.pem -inform PEM -noout -subject -issuer

【讨论】:

但 openssl verify -CAfile other_ca.pem self_signed_cert.pem 也返回 OK,见***.com/questions/65904954/…【参考方案5】:

您尝试过 BouncyCastle 库吗?

http://www.bouncycastle.org/wiki/display/JA1/Frequently+Asked+Questions

" 有用于处理属性证书、PKCS12、SMIME 和 OpenPGP 的特定示例程序。它们可以在包中找到:

org.bouncycastle.jce.examples org.bouncycastle.mail.smime.examples org.bouncycastle.openpgp.examples 另一个有用的示例来源是测试包:

org.bouncycastle.crypto.test org.bouncycastle.jce.provider.test org.bouncycastle.cms.test org.bouncycastle.mail.smime.test org.bouncycastle.openpgp.test org.bouncycastle.cert.test org.bouncycastle.pkcs.test org.bouncycastle.tsp.test "

【讨论】:

以上是关于查找证书是自签名的还是 CA 签名的的主要内容,如果未能解决你的问题,请参考以下文章

Apache 警告我的自签名证书是 CA 证书

MAC申请自签名的ssl证书

验证设备的自签名证书

PKI/CA X.509公钥证书

ssl

在 Windows 7 上信任 Java 7 的自签名证书