23

我正在使用该ecdsa.GenerateKey方法在 Go 中生成私钥/公钥对。我想将私钥存储在用户计算机上的文件中,并在程序启动时加载它。有一种方法elliptic.Marshal可以编组公钥,但没有编组私钥。我应该自己动手,还是有推荐的方法来存储私钥?

4

3 回答 3

33

这是一个代码示例,演示了 Go 中键的编码和解码。知道您需要连接几个步骤会有所帮助。加密算法是第一步,在本例中为 ECDSA 密钥。然后你需要标准编码,x509是最常用的标准。最后你需要一种文件格式,PEM 也是常用的一种。这是目前最常用的组合,但可以随意替换任何其他算法或编码。

func encode(privateKey *ecdsa.PrivateKey, publicKey *ecdsa.PublicKey) (string, string) {
    x509Encoded, _ := x509.MarshalECPrivateKey(privateKey)
    pemEncoded := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: x509Encoded})

    x509EncodedPub, _ := x509.MarshalPKIXPublicKey(publicKey)
    pemEncodedPub := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: x509EncodedPub})

    return string(pemEncoded), string(pemEncodedPub)
}

func decode(pemEncoded string, pemEncodedPub string) (*ecdsa.PrivateKey, *ecdsa.PublicKey) {
    block, _ := pem.Decode([]byte(pemEncoded))
    x509Encoded := block.Bytes
    privateKey, _ := x509.ParseECPrivateKey(x509Encoded)

    blockPub, _ := pem.Decode([]byte(pemEncodedPub))
    x509EncodedPub := blockPub.Bytes
    genericPublicKey, _ := x509.ParsePKIXPublicKey(x509EncodedPub)
    publicKey := genericPublicKey.(*ecdsa.PublicKey)

    return privateKey, publicKey
}

func test() {
    privateKey, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
    publicKey := &privateKey.PublicKey

    encPriv, encPub := encode(privateKey, publicKey)

    fmt.Println(encPriv)
    fmt.Println(encPub)

    priv2, pub2 := decode(encPriv, encPub)

    if !reflect.DeepEqual(privateKey, priv2) {
        fmt.Println("Private keys do not match.")
    }
    if !reflect.DeepEqual(publicKey, pub2) {
        fmt.Println("Public keys do not match.")
    }
}
于 2016-12-24T17:24:23.977 回答
9

我相信这些键的标准格式是使用 X.509 ASN.1 DER 表示。请参阅http://golang.org/pkg/crypto/x509/#MarshalECPrivateKeyhttp://golang.org/pkg/crypto/x509/#ParseECPrivateKey

于 2014-03-06T04:10:35.710 回答
0

我采用了一种非常快速而肮脏的方式来做到这一点,正如 15 年末在我的图书馆https://github.com/DaveAppleton/ether_go中的一个 geth 团队所建议的那样

这是一个简单得多的解决方案(但将钥匙放在显而易见的地方)

于 2018-12-04T22:36:10.270 回答