首页 > 解决方案 > 使用 ecsda 包验证 ECDSA 签名失败

问题描述

我已经生成了一个签名并对其进行了 base64 编码:

4d4559434951436c627834634e4b4d513944764d2f4d4f536c3636642f344f4f4c74777a48493661676e427a4149395838514968414c37683959464e575242784e56497675706b534b3362564b735049717a445067464e5a563164415a506565

使用公钥: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzIeFzpGyGzsHi66o07Hlzkv7T92dbSvDh5UIerOJl7l93RCc8VnvSm6MhuvKb4snojkUEMq0gDVb4fHlzSfzWw==

当我散列相同的消息并尝试验证它时,它失败了。

我正在使用crypto/ecsdaGo 中的包以及包中的SignASN1函数VerifyASN1

我已经编写了 2 个程序,一个用于签名,另一个用于在 go playground 中验证,但验证失败,可能是什么问题?

签署程序:https: //play.golang.org/p/D8KLurEelRI

验证程序:https: //play.golang.org/p/R7ZUBnvCJ0o

注意:函数在 go 版本 15 及更高版本中可用。

要签名的程序代码

package main

import (
    "crypto/ecdsa"
    "crypto/rand"
    "fmt"
    "encoding/base64"
    "crypto/x509"
    "crypto/sha256"
)

func main() {
        prik ,ee := base64.StdEncoding.DecodeString("MHcCAQEEIOjE1zQtdzs10msOj4JuX6URIDJOVg5AaR8wCtEM227ZoAoGCCqGSM49AwEHoUQDQgAEzIeFzpGyGzsHi66o07Hlzkv7T92dbSvDh5UIerOJl7l93RCc8VnvSm6MhuvKb4snojkUEMq0gDVb4fHlzSfzWw==")
        if ee != nil{
        panic(ee)
        }
        
        privateKey, e := x509.ParseECPrivateKey(prik)
        if e != nil{
        panic(e)
        }
        

    msg := "6e80bec4-1"
    hash := sha256.Sum256([]byte(msg))
    sig, err := ecdsa.SignASN1(rand.Reader, privateKey, hash[:])
    
    if err != nil {
        panic(err)
    }
    fmt.Printf("signature: %x\n", base64.StdEncoding.EncodeToString(sig))

    
    
    
    
       
}

验证签名的程序。

package main

import (
    "crypto/ecdsa"
    "fmt"
    "encoding/base64"
    "crypto/x509"
    "crypto/sha256"
)

func main() {
    pubkdata, _ := base64.StdEncoding.DecodeString("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzIeFzpGyGzsHi66o07Hlzkv7T92dbSvDh5UIerOJl7l93RCc8VnvSm6MhuvKb4snojkUEMq0gDVb4fHlzSfzWw==")
    sig, _ := base64.StdEncoding.DecodeString("4d4559434951436c627834634e4b4d513944764d2f4d4f536c3636642f344f4f4c74777a48493661676e427a4149395838514968414c37683959464e575242784e56497675706b534b3362564b735049717a445067464e5a563164415a506565")
    PK, _:= x509.ParsePKIXPublicKey(pubkdata)
    //Validate the signture
    
    msg := "6e80bec4-1"
    hash := sha256.Sum256([]byte(msg))
    valid := ecdsa.VerifyASN1(PK.(*ecdsa.PublicKey), hash[:], sig)
    fmt.Println("signature verified:", valid)
}

结果:signature verified: false

标签: gocryptographyecdsa

解决方案


您正在使用十六进制表示打印出签名的 base64:

fmt.Printf("signature: %x\n", base64.StdEncoding.EncodeToString(sig))

之后,您尝试将输出解析为 base64,这就是您得到不同结果的原因。用 替换打印格式%s,它应该可以工作:

fmt.Printf("signature: %s\n", base64.StdEncoding.EncodeToString(sig))

推荐阅读