无法验证Go中的SHA256签名。

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

Unable to verify SHA256 signature in go

问题

我一直在尝试使用Go的crypto包验证在Node中生成的签名。签名是使用createSig()函数生成的。然后在Go中,我使用verifySig()函数进行验证,但是验证总是失败。这些私钥/公钥是安全的,可以共享,因为它们是为了这个示例而生成的。我能够在Node中从签名中运行验证而没有问题,但是我不确定在Go中出现了什么问题导致验证失败。

在Node中生成签名:

  1. function createSig() {
  2. const crypto = require("crypto");
  3. function fromBase64(base64) {
  4. return base64.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
  5. }
  6. const PRIVATE_KEY =
  7. "-----BEGIN PRIVATE KEY-----\nMIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAyX1juQ2AVhS5NdKl\nJL5g4A+fPLUUWh2Tq1+f0Z1rb1dpCZ+RXECJAdW4ocsl5n24QtmzD66Z/s1bs+B5\nOyD4KwIDAQABAkBqxbiXsrDkbNzsybBbtUsO0Rh4Chk729qKAQVnBf2NpRmz3KAf\nMXP5M9Wr9HlD1PT8WUUaYvGtabbbkXTFq+pBAiEA+T2Lja3seY2NUxsR0Qi211Ug\nKCd820+5Tjft1XMf1aECIQDO9FDm5asV3q60YvqpifSawiS2JH/DS7Whg4X0M64i\nSwIhAPaKTY/g+eim/6O0RCRspUhNeRifLt9VdiyMIGOilFvhAiAJxgH4FYqR2tVX\nUYFS9l/l2xtOusSJ3Y5zVTnDQZmMpwIhAMibeam8MvHMr3FjTqE5CwOgsg6zXiWZ\nFA9ZnEINP5jz\n-----END PRIVATE KEY-----";
  8. var message = "test";
  9. var signer = crypto.createSign("RSA-SHA256");
  10. signer.update(message);
  11. return fromBase64(signer.sign(PRIVATE_KEY, "base64"));
  12. }

在Go中进行验证:

  1. func verifySig(message, signature string) (bool, error) {
  2. var key = "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMl9Y7kNgFYUuTXSpSS+YOAPnzy1FFod\nk6tfn9Gda29XaQmfkVxAiQHVuKHLJeZ9uELZsw+umf7NW7PgeTsg+CsCAwEAAQ==\n-----END PUBLIC KEY-----"
  3. block, _ := pem.Decode([]byte(key))
  4. if block == nil {
  5. return false, errors.New("uh oh")
  6. }
  7. sh := crypto.SHA256.New()
  8. sh.Write([]byte(message))
  9. hashed := sh.Sum(nil)
  10. pub, err := x509.ParsePKIXPublicKey(block.Bytes)
  11. if err != nil {
  12. return false, err
  13. }
  14. if pubKey, ok := pub.(*rsa.PublicKey); ok {
  15. err := rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, hashed, []byte(signature))
  16. if err != nil {
  17. // 每次都在这里失败
  18. return false, err
  19. }
  20. return true, nil
  21. }
  22. }

在Node中的验证工作正常:

  1. function verifySig(message, signature) {
  2. const PUBLIC_KEY =
  3. "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMl9Y7kNgFYUuTXSpSS+YOAPnzy1FFod\nk6tfn9Gda29XaQmfkVxAiQHVuKHLJeZ9uELZsw+umf7NW7PgeTsg+CsCAwEAAQ==\n-----END PUBLIC KEY-----";
  4. var verifier = crypto.createVerify("RSA-SHA256");
  5. verifier.update(message);
  6. // 将返回true
  7. return verifier.verify(PUBLIC_KEY, signature, "base64");
  8. }
英文:

I have been trying to verify a signature generated in Node with the go crypto package. The signature is generated from the createSig() function. Then in go I am verifying that with verifySig() but it always fails. These private/public keys are safe to share as they were generated for this example. I was able to run a verification in Node from the signature without an issue but I'm not sure what's happening in go to make it fail.

Generating signature in Node

  1. function createSig() {
  2. const crypto = require("crypto");
  3. function fromBase64(base64) {
  4. return base64.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
  5. }
  6. const PRIVATE_KEY =
  7. "-----BEGIN PRIVATE KEY-----\nMIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAyX1juQ2AVhS5NdKl\nJL5g4A+fPLUUWh2Tq1+f0Z1rb1dpCZ+RXECJAdW4ocsl5n24QtmzD66Z/s1bs+B5\nOyD4KwIDAQABAkBqxbiXsrDkbNzsybBbtUsO0Rh4Chk729qKAQVnBf2NpRmz3KAf\nMXP5M9Wr9HlD1PT8WUUaYvGtabbbkXTFq+pBAiEA+T2Lja3seY2NUxsR0Qi211Ug\nKCd820+5Tjft1XMf1aECIQDO9FDm5asV3q60YvqpifSawiS2JH/DS7Whg4X0M64i\nSwIhAPaKTY/g+eim/6O0RCRspUhNeRifLt9VdiyMIGOilFvhAiAJxgH4FYqR2tVX\nUYFS9l/l2xtOusSJ3Y5zVTnDQZmMpwIhAMibeam8MvHMr3FjTqE5CwOgsg6zXiWZ\nFA9ZnEINP5jz\n-----END PRIVATE KEY-----";
  8. var message = "test";
  9. var signer = crypto.createSign("RSA-SHA256");
  10. signer.update(message);
  11. return fromBase64(signer.sign(PRIVATE_KEY, "base64"));
  12. }

Verifying in go

  1. func verifySig(message, signature string) (bool, error) {
  2. var key = "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMl9Y7kNgFYUuTXSpSS+YOAPnzy1FFod\nk6tfn9Gda29XaQmfkVxAiQHVuKHLJeZ9uELZsw+umf7NW7PgeTsg+CsCAwEAAQ==\n-----END PUBLIC KEY-----"
  3. block, _ := pem.Decode([]byte(key))
  4. if block == nil {
  5. return false, errors.New("uh oh")
  6. }
  7. sh := crypto.SHA256.New()
  8. sh.Write([]byte(message))
  9. hashed := sh.Sum(nil)
  10. pub, err := x509.ParsePKIXPublicKey(block.Bytes)
  11. if err != nil {
  12. return false, err
  13. }
  14. if pubKey, ok := pub.(*rsa.PublicKey); ok {
  15. err := rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, hashed, []byte(signature))
  16. if err != nil {
  17. // THIS IS WHERE I END UP EVERY TIME
  18. return false, err
  19. }
  20. return true, nil
  21. }
  22. }

Working Node verification:

  1. function verifySig(message, signature) {
  2. const PUBLIC_KEY =
  3. "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMl9Y7kNgFYUuTXSpSS+YOAPnzy1FFod\nk6tfn9Gda29XaQmfkVxAiQHVuKHLJeZ9uELZsw+umf7NW7PgeTsg+CsCAwEAAQ==\n-----END PUBLIC KEY-----";
  4. var verifier = crypto.createVerify("RSA-SHA256");
  5. verifier.update(message);
  6. // will return true
  7. return verifier.verify(PUBLIC_KEY, signature, "base64");
  8. }

答案1

得分: 1

我认为你的代码有两个问题。

第一个问题:在Node.js中,你使用Base64对签名进行了编码,第二个问题:然后你将Base64字符串转换为“UrlSafe” Base64编码的字符串。

这两个步骤需要反转(我不知道Go语言是否有内置的“Url-safe Base64解码函数”),然后再将签名字符串作为输入用于Go语言中的验证。

英文:

I think there are 2 issues with your code.

First: in NodeJs you encoded the signature using Base64 and secondly you converted the Base64 string to a "UrlSafe" Base64-encoded string.

Those two steps need to be reversed (I don't know if Go has a built-in "Url-safe Base64 decoding function") before you use the signature string as input for your verification in Go.

huangapple
  • 本文由 发表于 2021年6月29日 07:19:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/68170946.html
匿名

发表评论

匿名网友

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

确定