当前位置: 首页 > 知识库问答 >
问题:

如何从其私钥生成ECDSA公钥?

钱建本
2023-03-14

以下网站经常被引用,而且我认为是准确的:

https://gobittest.appspot.com/Address

我试图在Golang中重现这些步骤,但第一步就失败了:-(

有人能给我提供一个Golang片段,给定ECDSA私钥,返回公钥吗?我想我可能具体指的是上述站点html" target="_blank">示例中的私钥指数和公钥指数。

i、 例如,给定随机生成的(十六进制编码的)私钥(指数?)<代码>E83385AF76B2B1997326B567461BF73DD9C27EAB9E1E86D26779F4650C5F2B75返回公钥04369D83469A6690F31E4CF3BD92CB0BC20C6E88CE010DFA43E5F08BC49D11DA87970D4703B3ADBC9A140B03A0797A6DE377C80C369FE76A0F45A79D3F

我发现了许多(相关的)结果:

https://crypto.stackexchange.com/questions/5756/how-to-generate-a-public-key-from-a-private-ecdsa-key

但是没有一个包括明确的例子。

Go的加密/ecdsa模块允许生成密钥,并在类型上包含公共,但这将返回公钥属性。

从私钥开始的替代方法似乎需要经过PEM编码(包括DER编码的ASN)形式的密钥,这感觉很迂回(我需要构造)。

参见下面的答案:andrew-w-phillips@和kelsnare@提供了(相同|正确)的解决方案。感谢他们两个!

对于后代,比特币(和以太坊)使用由secp256k1定义的椭圆曲线。andrew-w-phillips@的以下代码和kelsnare@使用以太坊对此曲线的实现,有效:

import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "fmt"
    "math/big"
    "strings"

    "github.com/ethereum/go-ethereum/crypto/secp256k1"
)
func Public(privateKey string) (publicKey string) {
    var e ecdsa.PrivateKey
    e.D, _ = new(big.Int).SetString(privateKey, 16)
    e.PublicKey.Curve = secp256k1.S256()
    e.PublicKey.X, e.PublicKey.Y = e.PublicKey.Curve.ScalarBaseMult(e.D.Bytes())
    return fmt.Sprintf("%x", elliptic.Marshal(secp256k1.S256(), e.X, e.Y))
}
func main() {
    privateKey := "E83385AF76B2B1997326B567461FB73DD9C27EAB9E1E86D26779F4650C5F2B75"
    log.Println(strings.ToUpper(Public(privateKey)))
}

收益 率:

04369D83469A66920F31E4CF3BD92CB0BC20C6E88CE010DFA43E5F08BC49D11DA87970D4703B3ADBC9A140B4AD03A0797A6DE2D377C80C369FE76A0F45A7A39D3F

共有2个答案

韦望
2023-03-14

我没有那么低级,但可能是这样的:

var pri ecdsa.PrivateKey
pri.D, _ = new(big.Int).SetString("E83385AF76B2B1997326B567461FB73DD9C27EAB9E1E86D26779F4650C5F2B75",16)
pri.PublicKey.Curve = elliptic.P256()
pri.PublicKey.X, pri.PublicKey.Y = pri.PublicKey.Curve.ScalarBaseMult(pri.D.Bytes())
越俊驰
2023-03-14

在阅读了Andrew W.Phillips的答案和来自https://github.com/bitherhq/go-bither/tree/release/1.7/crypto

package main

import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
    "fmt"
    "log"
    "math/big"
)

func PubBytes(pub *ecdsa.PublicKey) []byte {
    if pub == nil || pub.X == nil || pub.Y == nil {
        return nil
    }
    return elliptic.Marshal(elliptic.P256(), pub.X, pub.Y)
}

func toECDSAFromHex(hexString string) (*ecdsa.PrivateKey, error) {
    pk := new(ecdsa.PrivateKey)
    pk.D, _ = new(big.Int).SetString(hexString, 16)
    pk.PublicKey.Curve = elliptic.P256()
    pk.PublicKey.X, pk.PublicKey.Y = pk.PublicKey.Curve.ScalarBaseMult(pk.D.Bytes())
    return pk, nil
}

func main() {
    pHex := "E83385AF76B2B1997326B567461FB73DD9C27EAB9E1E86D26779F4650C5F2B75"
    pk, err := toECDSAFromHex(pHex)
        if err != nil {
        log.Fatal(err.Error())
    }
    fmt.Printf("Generated Public Key: %x\n", PubBytes(&pk.PublicKey))

    hash := []byte("Hello Gopher!")

    fmt.Printf("\nSigning...\n\n")
    r, s, err := ecdsa.Sign(rand.Reader, pk, hash)
    if err != nil {
        log.Fatal(err.Error())
    }
    fmt.Printf("\nVerifying..\n\n")
    if ecdsa.Verify(&pk.PublicKey, hash, r, s) {
        fmt.Println("Success!!")
    } else {
        fmt.Println("Failure!!")
    }
}
// Output
// Generated Public Key: 04265a5015c0cfd960e5a41f35e0a87874c1d8a28289d0d6ef6ac521ad49c3d80a8a7019ceef189819f066a947ad5726db1a4fe70a3208954c46b0e60f2bf7809c
// 
// Signing...
// 
// 
// Verifying..
// 
// Success!!

==原始答案===========

Dunno大部分加密,但加密/椭圆有一个元帅函数

所以,一旦你有了一个私钥,也许下面的就可以了

import (
  "crypto/elliptic"
  "crypto/ecdsa"
)
var privKey *ecdsa.PrivateKey
func main() {
  // some init to privKey
  pk := privKey.PublicKey()
  keybuf := elliptic.Marshal(pk.Curve, pk.X, pk.Y)
  log.Printf("Key: %s\n", string(keybuf))
}

我在黑暗中拍摄希望能有帮助

 类似资料:
  • 问题内容: 我试图从私钥生成公共ECDSA密钥,但是在Internet上如何进行此操作方面,我还没有找到太多帮助。几乎所有内容都是根据公共密钥规范生成公共密钥的,我不知道该如何获得。到目前为止,这是我汇总的内容: 但是,在运行时,出现以下错误: 我究竟做错了什么?有没有更好/更简便的方法可以做到这一点? 编辑:我设法获得一些代码进行编译,但不能正常工作: 当我运行它时,它会生成一个publicKe

  • 我试图从私钥中生成一个公共ECDSA密钥,但我还没有在互联网上找到多少关于如何实现这一点的帮助。几乎所有的事情都是为了从公钥规范生成公钥,我不知道如何得到它。到目前为止,我总结了以下内容: 但是,在运行时,我会出现以下错误: 我做错了什么?有更好/更简单的方法吗? 编辑:我已经设法编译了一些代码,但它不能正常工作: 当我运行它时,它会生成一个公钥,但它不是私钥对应的公钥。

  • 从这里我指出了自己如何获得公钥,并使用EC_POINT_bn2point,而不是hex2point,根据OpenSSL源代码,它在内部执行BN_hex2bn。 那么,为什么EC_POINT_bn2point返回null呢?我正在认真考虑重新编译OpenSSL,并放一些调试例程来找出它失败的原因。

  • 我正在尝试用c#签署比特币交易。我有两段代码要完成。我可以使用Bouncy castle创建一组私钥和公钥。我可以将其转换为钱包导入格式ok。 我还可以从ECDSA公钥生成比特币地址。 然而,我想签署一项交易,我所拥有的只是我的私钥。我不想把东西放进钱包里签名。那么,在只提供私钥的情况下,如何生成公钥呢? 我发现了一个javascript方法可以做到这一点: 我在充气城堡看到的唯一方法是生成随机一

  • 我正试图使用弹跳城堡来生成ECDSA密钥。从Java的角度来看,代码似乎工作得很好;但是,当我转储文件并试图验证数据时,OpenSSL不喜欢数据的格式。 经过一些研究,我认为bouncy castle正在将私钥编码为公钥。 null

  • 我已经阅读了如何在OpenSSL中从ECDSA私钥获取公钥? 并想做同样的事情,但在Java中与充气城堡。 我也见过Bouncy Castle ESCDA从私钥创建公钥,但这并没有帮助。