英文:
How to store ECDSA private key in Go
问题
我正在使用ecdsa.GenerateKey
方法在Go中生成私钥/公钥对。我想将私钥存储在用户计算机上的文件中,并在程序启动时加载它。有一个名为elliptic.Marshal
的方法可以序列化公钥,但没有针对私钥的方法。我应该自己编写代码来实现,还是有推荐的存储私钥的方法?
英文:
I am using the ecdsa.GenerateKey
method to generate a private/public key pair in Go. I would like to store the private key in a file on the users computer, and load it whenever the program starts. There is a method elliptic.Marshal
that marshals the public key, but nothing for the private key. Should I simply roll my own, or is there a recommended way to store the private key?
答案1
得分: 43
以下是一个演示在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.")
}
}
希望对您有所帮助!
英文:
Here is a code sample that demonstrates encoding and decoding of keys in Go. It helps to know that you need to connect couple of steps. Crypto algorithm is the fist step, in this case ECDSA key. Then you need standard encoding, x509 is most commontly used standard. Finally you need a file format, PEM is again commonly used one. This is currently most commonly used combination, but feel free to substitute any other algoriths or encoding.
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.")
}
}
答案2
得分: 10
我相信这些密钥的标准格式是使用X.509 ASN.1 DER表示。请参考http://golang.org/pkg/crypto/x509/#MarshalECPrivateKey和http://golang.org/pkg/crypto/x509/#ParseECPrivateKey。
英文:
I believe the standard format for those keys is to use the X.509 ASN.1 DER representation. See http://golang.org/pkg/crypto/x509/#MarshalECPrivateKey and http://golang.org/pkg/crypto/x509/#ParseECPrivateKey.
答案3
得分: 0
我采用了一个非常快速而简单的方法来实现它,正如'15年末geth团队中的一位成员在我的库https://github.com/DaveAppleton/ether_go中建议的那样。
这是一个更简单的解决方案(但会将密钥显示出来)。
英文:
I adapted a really quick and dirty way to do it, as suggested by one of the geth team in late '15 in my library https://github.com/DaveAppleton/ether_go
it is a far simpler solution (but puts keys in plain sight)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论