从 PEM 文件加载(openssl 生成)DSA 私钥

我正在尝试在我的程序中加载一个 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。有任何想法吗?


PS:我找不到任何通过 Internet 加载 DSA 私钥 pem 文件的示例。


拉风的咖菲猫
浏览 464回答 1
1回答

ITMISS

花了几个小时后,我设法解决了我的问题,我发布了我的发现,这样可以节省一些人的时间:首先,我使用这个很棒的在线工具查看了我的 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 应该在标准库中处理此类问题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go