简体   繁体   English

Golang:使用与指定公钥对应的私钥验证x509证书是否已签名

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

I want to get an X509 certificate verified to make sure it was signed by the private key that corresponds to the public key: 我希望验证X509证书以确保它是由与公钥对应的私钥签名的:

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

It seems to me that certificate.CheckSignature method is the right way to go but I can not figure out the parameters it needs and would like to ask for community's help. 在我看来, certificate.CheckSignature方法是正确的方法,但我无法弄清楚它需要的参数,并希望得到社区的帮助。

Btw, I was able to do the same in java (working on two adjacent projects). 顺便说一句,我能够在java中做同样的事情(处理两个相邻的项目)。 It looks like this: 它看起来像这样:

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);

I appreciate any hints on the field! 我很欣赏这个领域的任何暗示! P. P.

If I properly understood what you are trying to do, then answer is simple. 如果我理解你想要做什么,那么回答很简单。

Your certificate includes the public key. 您的证书包含公钥。 So all you need is to compare your public key with the public key from the certificate. 因此,您只需要将公钥与证书中的公钥进行比较。 The code looks like: 代码如下:

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")
}

Update 更新

Just checked OpenJDK implementation of .verify method . 刚刚检查了OpenJDK 实现的.verify方法 Looks like there can be situation when certificate doesn't contain the public key and you actually need to verify signature. 看起来可能存在证书不包含公钥并且您确实需要验证签名的情况。 The Go code for this case looks like this: 这种情况的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")
}

Thanks Roman, I've managed to get it working like this: 谢谢Roman,我设法让它像这样工作:

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

So, that's basically what you recommended but with the use of sha1 hash instead - this is what I get for the certificate I generated locally. 所以,这基本上是你推荐的,但是使用了sha1哈希 - 这就是我在本地生成的证书所获得的。 I've also managed to get it working by temporary swapping certificate's public key with the key I would like to verify against: 我还设法通过临时交换证书的公钥以及我想要验证的密钥来使其工作:

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

The second approach looks hack-ish of course but both of them work as expected... 第二种方法看起来很糟糕,但它们都按预期工作......

Wonder if it is possible to figure out whether it is SHA1 or SHA256 at runtime? 想知道是否可以在运行时确定它是SHA1还是SHA256?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM