英文:
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")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论