为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
蝴蝶刀刀 2023-01-03 11:15:43
我尝试使用 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 xyzimport (    "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}
查看完整描述

1 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

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/


查看完整回答
反对 回复 2023-01-03
  • 1 回答
  • 0 关注
  • 208 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号