我在GO中使用ecdsa.GenerateKey方法生成私钥/公钥对.我想将私钥存储在用户计算机上的一个文件中,并在程序启动时加载它.存在编组公钥的方法elliptic.Marshal,但没有用于私钥的方法elliptic.Marshal.我应该简单地滚动我自己的密钥,或者有推荐的存储私钥的方法吗?

推荐答案

下面是一个代码示例,它演示了围棋中键的编码和解码.了解您需要连接几个步骤会有所帮助.加密算法是第一步,在本例中是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.")
    }
}

Go相关问答推荐

CGO Linux到Windows交叉编译中的未知类型名称

为什么工具链指令在这种情况下没有效果?

为什么Slices包中的函数定义Slice参数的类型参数?

埃拉托塞尼筛:加快交叉关闭倍数步骤

如何在出现错误时停止从通道读取?

go aws-lambda 与 terraform 中的 exec 格式错误

如果第一次匹配条件,如何跳过切片中的值

我怎样才能改进这个嵌套逻辑以使其正常工作并提高性能

go-jwt 令牌验证错误 - 令牌签名无效:密钥类型无效

按位移计算结果中的差异

使用Goldmark在golang中添加ChildNode会导致堆栈溢出

Golang 到 wasm 编译使用 tinygo.使用 wasmtime 执行

泛型:实现嵌套接口

设置指向空接口的指针

GOLANG:为什么 SetDeadline/SetReadDeadline/SetWriteDeadline 在使用 os.File.Fd() 时对文件不起作用?

如何使用 math/big 对 bigInt 进行取模?

在 Golang 中获取谷歌云服务帐户的访问令牌?

Go lang - 惯用的默认后备

如何在 docker 文件中安装 golang 包?

Gin中测试模式有什么用