Go 加密库创建的 PKCS1 公钥与“openssl rsa ...”之间的区别

我尝试使用 Go 的 rsa 和 x509 包生成一对 PKCS8 编码的私钥和相应的 PKCS1 编码的公钥。我希望具有与以下 openssl 命令相同的行为:


$ openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt

$ openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub

我在下面添加了我的 Go 实现,归结为要点。为了使用它,我首先使用GeneratePrivateKey生成一个私钥(最后附上的示例的位大小为2048),然后使用以下两种方法对私钥和公钥进行编码。


但是,当运行第二个 openssl 命令以在由我的 Go 实现编码的私钥上对公钥进行编码时,公钥不同(我在下面提供了一个差异示例)。特别是,它看起来好像 openssl 输出通过前缀扩展了我的 Go 实现的输出。


我将不胜感激对差异的任何解释(在最好的情况下,我将如何修复我的代码)。非常感谢你!


我的 Go 代码如下所示:


package xyz


import (

    "crypto/rand"

    "crypto/rsa"

    "crypto/x509"

    "encoding/pem"

)


func GeneratePrivateKey(bitSize int) (*rsa.PrivateKey, error) {

    privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)

    if err != nil {

        return nil, err

    }

    err = privateKey.Validate()

    if err != nil {

        return nil, err

    }

    return privateKey, nil

}


func EncodePrivateKeyToPEM(privateKey *rsa.PrivateKey) (string, error) {

    privateDER, err := x509.MarshalPKCS8PrivateKey(privateKey)

    if err != nil {

        return "", err

    }

    privateBlock := pem.Block{

        Type:    "RSA PRIVATE KEY",

        Headers: nil,

        Bytes:   privateDER,

    }

    privatePEM := pem.EncodeToMemory(&privateBlock)

    return string(privatePEM), nil

}


蝴蝶刀刀
浏览 209回答 1
1回答

慕盖茨4494581

OpenSSL 语句生成 PKCS#8 格式的私钥和 X.509/SPKI 格式的公钥,均采用 PEM 编码。使用 Go Code 生成的私钥具有 PKCS#8 格式,但 PEM 编码使用了错误的页眉和页脚(正确的是-----BEGIN PRIVATE KEY-----和-----END PRIVATE键----- )。解决方法是EncodePrivateKeyToPEM()在pem.Block()调用中相应地调整类型 ( Type: "PRIVATE KEY")。对于使用 Go 代码生成的公钥,情况正好相反:这里,页眉和页脚对应于 PEM 编码的 X.509/SPKI 密钥的页眉和页脚。但是,正文是 PKCS#1 格式的。这就是密钥不同的原因。解决方法是在EncodePublicKeyToPEM()方法MarshalPKIXPublicKey()中使用 X.509/SPKI 格式而不是MarshalPKCS1PublicKey().顺便说一句,检查密钥的最佳方法是使用 ASN.1 解析器,例如https://lapo.it/asn1js/。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go