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

huangapple go评论90阅读模式
英文:

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

问题

我想要验证一个X509证书,以确保它是由对应于公钥的私钥签名的:

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

在我看来,certificate.CheckSignature 方法是正确的方法,但我无法弄清楚它需要哪些参数,希望能得到社区的帮助。

顺便说一下,我在Java中也能做到同样的事情(在两个相邻的项目上工作)。代码如下:

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

// 验证该证书是否使用与指定公钥对应的私钥进行签名。
certificate.verify(publicKey);

非常感谢对这个领域的任何提示!
P.

英文:

I want to get an X509 certificate verified to make sure it was signed by the private key that corresponds to the public key:

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.

Btw, I was able to do the same in java (working on two adjacent projects). 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.

答案1

得分: 4

谢谢Roman,我已经成功按照以下方式使其工作:

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

所以,基本上就是你建议的方法,但是使用了sha1哈希 - 这是我在本地生成的证书所得到的结果。我还成功地通过临时交换证书的公钥和我想要验证的密钥来使其工作:

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

第二种方法看起来有点像黑客行为,但两种方法都能按预期工作...

不知道是否可能在运行时确定是SHA1还是SHA256?

英文:

Thanks Roman, I've managed to get it working like this:

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. 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?

答案2

得分: 2

如果我正确理解你的意图,那么答案很简单。

你的证书包含了公钥。所以你只需要将你的公钥与证书中的公钥进行比较。代码如下:

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的.verify方法的实现,看起来有可能出现证书不包含公钥的情况,实际上你需要验证签名。这种情况下的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")
}
英文:

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. 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:

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

huangapple
  • 本文由 发表于 2017年3月2日 23:44:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/42559806.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定