从 PEM 文件加载(openssl 生成的)DSA 私钥
Load (openssl generated) DSA private key from PEM file
我正在尝试在我的程序中加载 dsa 私钥,以下是我的处理方法:
我使用 openssl 创建了一个 dsa 密钥对:
openssl dsaparam -genkey 2048 -out dsakey.pem
我用下面的函数来解析pem文件
func getDSAPrivateKeyFromPemFile(pemfilepath string) (recoveredprivateKey *dsa.PrivateKey, err error) {
pemfile, err := os.Open(pemfilepath)
if err != nil {
return nil, err
}
recoveredbytes, err := ioutil.ReadAll(pemfile)
if err != nil {
return nil, err
}
recoveredpemdsaparameteres, rest := pem.Decode(recoveredbytes)
if recoveredpemdsaparameteres == nil {
return nil, errors.New("No pem recovered")
}
_, err = asn1.Unmarshal(append(recoveredpemdsaparameteres.Bytes, recoveredpemdsaprivatekey.Bytes...), recoveredprivateKey)
if err != nil {
return nil, err
}
fmt.Printf("PEM:%v\n", recoveredpemdsaparameteres)
recoveredpemdsaprivatekey, _ := pem.Decode(rest)
fmt.Printf("PEM:%v\n", recoveredpemdsaprivatekey)
pemfile.Close()
}
当我调用这个函数失败时:
panic: reflect: call of reflect.Value.Type on zero Value
goroutine 1 [running]:
reflect.Value.Type(0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/reflect/value.go:1664 +0x7b
encoding/asn1.parseField(0x0, 0x0, 0x0, 0xc8200b0600, 0x58b, 0x600, 0x0, 0x0, 0x0, 0x0, ...)
/usr/local/go/src/encoding/asn1/asn1.go:558 +0xbd
encoding/asn1.UnmarshalWithParams(0xc8200b0600, 0x58b, 0x600, 0x1383e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
/usr/local/go/src/encoding/asn1/asn1.go:957 +0x16e
encoding/asn1.Unmarshal(0xc8200b0600, 0x58b, 0x600, 0x1383e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/encoding/asn1/asn1.go:950 +0x8f
main.getDSAPrivateKeyFromPemFile(0x1e7fa0, 0x26, 0x0, 0x0, 0x0)
但是,我可以在输出中完美地看到我的 dsa 密钥:
PEM:&{DSA PARAMETERS map[] [48 130 2 45 2 130...]}
PEM:&{DSA PRIVATE KEY map[] [48 130 3 86 2 1 0 ...]}
问题实际上是如何将 pem 字节解组为 dsa.PrivateKey。
有什么想法吗?
P.S:我无法在互联网上找到任何加载 DSA 私钥 pem 文件的示例。
花了几个小时后,我设法解决了我的问题
我 post 我的发现可能会节省一些人的时间:
首先,我使用这个很棒的在线工具检查了我的 pem 文件编码:http://lapo.it/asn1js/。直到那时我才意识到 go 期望 pem 文件具有不同的结构......不好!
之后,不难将文件中的每个值与相应的 dsa.PrivateKey 结构相关联。
因此,我创建了一个新结构并将其命名为 MyPrivateKey,其顺序与 pem 文件相同:
type MyPrivateKey struct {
E1, P, Q, G, Y, X *big.Int
}
然后,我没有尝试直接解组为 dsa.PrivateKey,而是将 asn1 编码值解组为我自制的结构。奇迹般地奏效了。这是修改后的函数:
func getDSAPrivateKeyFromPemFile(pemFilePath string) (privateKey *dsa.PrivateKey, err error) {
pemfile, err := os.Open(pemFilePath)
if err != nil {
return nil, err
}
recoveredBytes, err := ioutil.ReadAll(pemfile)
if err != nil {
return nil, err
}
pemfile.Close()
pemDSAParameters, rest := pem.Decode(recoveredBytes)
if pemDSAParameters == nil {
return nil, errors.New("No pem recovered")
}
pemDSAPrivateKey, _ := pem.Decode(rest)
keyParameters := dsa.Parameters{G: big.NewInt(0), P: big.NewInt(0), Q: big.NewInt(0)}
_, err = asn1.Unmarshal(pemDSAParameters.Bytes, &keyParameters)
if err != nil {
return nil, err
}
//fmt.Printf("\n\n\n\n\n\nP:%x\n\nG:%x\n\nQ:%x\n\n\n\n\n\n", keyParameters.P, keyParameters.G, keyParameters.Q)
myPrivateKey := MyPrivateKey{}
_, err = asn1.Unmarshal(pemDSAPrivateKey.Bytes, &myPrivateKey)
if err != nil {
return nil, err
}
//fmt.Printf("\nprivate\nE1:%x\n\nP:%x\n\nQ:%x\n\nG:%x\n\nY:%x\nX:%x\n\n\n\n", myPrivateKey.E1, myPrivateKey.P, myPrivateKey.Q, myPrivateKey.G, myPrivateKey.Y, myPrivateKey.X)
privateKey = &dsa.PrivateKey{}
privateKey.Parameters = keyParameters
privateKey.X = myPrivateKey.X
return privateKey, nil
}
也许有更简单的方法来解决这一切,我只是忽略了!如果您知道更好的方法,请成为我的客人!否则,我相信 go 应该在标准库中处理这类问题。
我正在尝试在我的程序中加载 dsa 私钥,以下是我的处理方法:
我使用 openssl 创建了一个 dsa 密钥对:
openssl dsaparam -genkey 2048 -out dsakey.pem
我用下面的函数来解析pem文件
func getDSAPrivateKeyFromPemFile(pemfilepath string) (recoveredprivateKey *dsa.PrivateKey, err error) { pemfile, err := os.Open(pemfilepath) if err != nil { return nil, err } recoveredbytes, err := ioutil.ReadAll(pemfile) if err != nil { return nil, err } recoveredpemdsaparameteres, rest := pem.Decode(recoveredbytes) if recoveredpemdsaparameteres == nil { return nil, errors.New("No pem recovered") } _, err = asn1.Unmarshal(append(recoveredpemdsaparameteres.Bytes, recoveredpemdsaprivatekey.Bytes...), recoveredprivateKey) if err != nil { return nil, err } fmt.Printf("PEM:%v\n", recoveredpemdsaparameteres) recoveredpemdsaprivatekey, _ := pem.Decode(rest) fmt.Printf("PEM:%v\n", recoveredpemdsaprivatekey) pemfile.Close() }
当我调用这个函数失败时:
panic: reflect: call of reflect.Value.Type on zero Value
goroutine 1 [running]:
reflect.Value.Type(0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/reflect/value.go:1664 +0x7b
encoding/asn1.parseField(0x0, 0x0, 0x0, 0xc8200b0600, 0x58b, 0x600, 0x0, 0x0, 0x0, 0x0, ...)
/usr/local/go/src/encoding/asn1/asn1.go:558 +0xbd
encoding/asn1.UnmarshalWithParams(0xc8200b0600, 0x58b, 0x600, 0x1383e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
/usr/local/go/src/encoding/asn1/asn1.go:957 +0x16e
encoding/asn1.Unmarshal(0xc8200b0600, 0x58b, 0x600, 0x1383e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/encoding/asn1/asn1.go:950 +0x8f
main.getDSAPrivateKeyFromPemFile(0x1e7fa0, 0x26, 0x0, 0x0, 0x0)
但是,我可以在输出中完美地看到我的 dsa 密钥:
PEM:&{DSA PARAMETERS map[] [48 130 2 45 2 130...]}
PEM:&{DSA PRIVATE KEY map[] [48 130 3 86 2 1 0 ...]}
问题实际上是如何将 pem 字节解组为 dsa.PrivateKey。 有什么想法吗?
P.S:我无法在互联网上找到任何加载 DSA 私钥 pem 文件的示例。
花了几个小时后,我设法解决了我的问题 我 post 我的发现可能会节省一些人的时间:
首先,我使用这个很棒的在线工具检查了我的 pem 文件编码:http://lapo.it/asn1js/。直到那时我才意识到 go 期望 pem 文件具有不同的结构......不好! 之后,不难将文件中的每个值与相应的 dsa.PrivateKey 结构相关联。 因此,我创建了一个新结构并将其命名为 MyPrivateKey,其顺序与 pem 文件相同:
type MyPrivateKey struct {
E1, P, Q, G, Y, X *big.Int
}
然后,我没有尝试直接解组为 dsa.PrivateKey,而是将 asn1 编码值解组为我自制的结构。奇迹般地奏效了。这是修改后的函数:
func getDSAPrivateKeyFromPemFile(pemFilePath string) (privateKey *dsa.PrivateKey, err error) {
pemfile, err := os.Open(pemFilePath)
if err != nil {
return nil, err
}
recoveredBytes, err := ioutil.ReadAll(pemfile)
if err != nil {
return nil, err
}
pemfile.Close()
pemDSAParameters, rest := pem.Decode(recoveredBytes)
if pemDSAParameters == nil {
return nil, errors.New("No pem recovered")
}
pemDSAPrivateKey, _ := pem.Decode(rest)
keyParameters := dsa.Parameters{G: big.NewInt(0), P: big.NewInt(0), Q: big.NewInt(0)}
_, err = asn1.Unmarshal(pemDSAParameters.Bytes, &keyParameters)
if err != nil {
return nil, err
}
//fmt.Printf("\n\n\n\n\n\nP:%x\n\nG:%x\n\nQ:%x\n\n\n\n\n\n", keyParameters.P, keyParameters.G, keyParameters.Q)
myPrivateKey := MyPrivateKey{}
_, err = asn1.Unmarshal(pemDSAPrivateKey.Bytes, &myPrivateKey)
if err != nil {
return nil, err
}
//fmt.Printf("\nprivate\nE1:%x\n\nP:%x\n\nQ:%x\n\nG:%x\n\nY:%x\nX:%x\n\n\n\n", myPrivateKey.E1, myPrivateKey.P, myPrivateKey.Q, myPrivateKey.G, myPrivateKey.Y, myPrivateKey.X)
privateKey = &dsa.PrivateKey{}
privateKey.Parameters = keyParameters
privateKey.X = myPrivateKey.X
return privateKey, nil
}
也许有更简单的方法来解决这一切,我只是忽略了!如果您知道更好的方法,请成为我的客人!否则,我相信 go 应该在标准库中处理这类问题。