Golang:验证 x509 证书是否使用与指定 public 密钥相对应的私钥签署

Golang: verify x509 certificate was signed using private key that corresponds to the specified public key

我想要验证 X509 证书以确保它是由对应于 public 密钥的私钥签署的:

var publicKey *rsa.PublicKey = getPublicKey()
var certificate *x509.Certificate = getCertificate()
certificate.CheckSignature(...)

在我看来 certificate.CheckSignature 方法是正确的方法,但我无法弄清楚它需要的参数,想寻求社区的帮助。

顺便说一句,我能够在 java 中做同样的事情(在两个相邻的项目上工作)。它看起来像这样:

RSAPublicKey publicKey = getPublicKey();
X509Certificate certificate = X509CertUtils.parse(...);

// Verifies that this certificate was signed using the
// private key that corresponds to the specified public key.
certificate.verify(publicKey);

我很感激现场的任何提示! P.

如果我正确地理解了你要做什么,那么答案就很简单了。

您的证书包含 public 密钥。因此,您只需将 public 密钥与证书中的 public 密钥进行比较。代码如下:

if certificate.PublicKey.(*rsa.PublicKey).N.Cmp(publicKey.(*rsa.PublicKey).N) == 0 && publicKey.(*rsa.PublicKey).E == certificate.PublicKey.(*rsa.PublicKey).E {
    println("Same key")
} else {
    println("Different keys")
}

更新

刚刚检查了 OpenJDK implementation of .verify method。看起来可能存在证书不包含 public 密钥并且您实际上需要验证签名的情况。此案例的 Go 代码如下所示:

h := sha256.New()
h.Write(certificate.RawTBSCertificate)
hash_data := h.Sum(nil)

err = rsa.VerifyPKCS1v15(publicKey.(*rsa.PublicKey), crypto.SHA256, hash_data, certificate.Signature)
if err != nil {
    println("Signature does not match")
}

谢谢罗曼,我已经设法让它像这样工作了:

hash := sha1.New()
hash.Write(certificate.RawTBSCertificate)
hashData := hash.Sum(nil)
rsa.VerifyPKCS1v15(dsPublicKey, crypto.SHA1, hashData, certificate.Signature)

所以,这基本上是您推荐的,但使用 sha1 散列代替 - 这就是我在本地生成的证书所获得的。我还设法通过临时交换证书的 public 密钥和我要验证的密钥来使其工作:

certificate.PublicKey = certificateAuthorityPublicKey
certificate.CheckSignature(x509.SHA1WithRSA, certificate.RawTBSCertificate, certificate.Signature) 

第二种方法当然看起来有点乱,但它们都按预期工作...

想知道是否可以在运行时判断它是 SHA1 还是 SHA256?