首页 > 解决方案 > 未能验证 ECDSA 签名

问题描述

我有一个签名:

3044022014d647cd08f1ea5b31d1e6539b6cbceb9182f6e7b2e29fb969354ef7e3434923022028bb4eda36af410149baa9​​36322e7c0e46cc5540a3aa89c811bc3c360028

哈希

f27c6c3aa42563c958292922be1e53fe107f4db0dfadba11122f0b12bf77f3ab

和一个公钥

04b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e6537a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b

下面是我验证签名的 Go 代码,但它失败了!我有信息表明这三个部分应该验证正常,并且其他人已经以其他方式验证了它们。所以我想知道这个 Go 代码中有什么错误让我得到错误的结果。

如果您想了解更多信息,此链接是关于我如何建立我的签名以及有人说他如何以其他方式验证成功。我现在很无奈: https ://bitcointalk.org/index.php?topic=4879014.msg43992837#msg43992837

package main

import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "encoding/hex"
    "fmt"
    "math/big"
)

func main() {
    pubkey, err := hex.DecodeString("b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e6537a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b")
    if err != nil {
        panic(err)
    }
    curve := elliptic.P256()
    // length
    keyLen := len(pubkey)

    x := big.Int{}
    y := big.Int{}
    x.SetBytes(pubkey[:(keyLen / 2)])
    y.SetBytes(pubkey[(keyLen / 2):])

    rawPubKey := ecdsa.PublicKey{curve, &x, &y}

    // hash
    hash, err := hex.DecodeString("f27c6c3aa42563c958292922be1e53fe107f4db0dfadba11122f0b12bf77f3ab")
    if err != nil {
        panic(err)
    }

    r := big.Int{}
    s := big.Int{}
    rr, err := hex.DecodeString("14d647cd08f1ea5b31d1e6539b6cbceb9182f6e7b2e29fb969354ef7e3434923")
    if err != nil {
        panic(err)
    }

    ss, err := hex.DecodeString("28bb4eda36af410149baa936322e7c0e46cc5540a3aa89c811bc3c360028bfd3")
    if err != nil {
        panic(err)
    }

    r.SetBytes(rr)
    s.SetBytes(ss)

    fmt.Printf("%v\n", ecdsa.Verify(&rawPubKey, hash[:], &r, &s))    
}

标签: goverifyecdsa

解决方案


您正在尝试使用错误的曲线。P-256,也称为secp256r1,与比特币中使用的曲线不同,即secp256k1。您的公钥与 P-256 上的一个点不对应(您可以使用 进行检查curve.IsOnCurve(&x, &y)),但它secp256k1 上的一个点。

Golang 不包括对比特币曲线的支持,因此您需要找到一个使用它执行 ECDSA 的库。

如果您使用正确的曲线,我可以确认签名确实验证了该密钥的数据。


推荐阅读