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

使用 x509.MarshalPKCS1PublicKey 从 go 生成 RSA 公钥

使用 x509.MarshalPKCS1PublicKey 从 go 生成 RSA 公钥

Go
交互式爱情 2022-05-10 14:11:07
我正在尝试从 go 生成一个公钥,如下所示:reader := rand.ReaderbitSize := 2048keypair, err := rsa.GenerateKey(reader, bitSize)这似乎有效并产生了一些有意义的东西。接下来,我想把它的公共部分写成这样的 RSA 文件:func PublicKeyToPemBytes(prvkey *rsa.PrivateKey) ([]byte, error) {    var pubkey *rsa.PublicKey    pubkey = &prvkey.PublicKey    pubkey_bytes := x509.MarshalPKCS1PublicKey(pubkey)    if pubkey_bytes == nil {        return nil, errors.New("Public key could not be serialized")    }    pubkey_pem := pem.EncodeToMemory(        &pem.Block{            Type:  "RSA PUBLIC KEY",            Bytes: pubkey_bytes,        },    )    return pubkey_pem, nil}这会产生一些看起来或多或少像你期望的东西。这是我生成的一个虚拟密钥,只是为了显示:-----BEGIN RSA PUBLIC KEY-----MIIBCGKCAQEAMU6KIRUM2KACW7ISHRVRVPXG5YC7+D58Y26HV3TBHJCDNYE9Z8NES/XOJS58SCJL+6VLCH03RQWFLSSBZRDTAFGE4V0PTZXQ1ECUIVX6EIUWAVIKTQA97WEBNFU4MCHVLWFPULDAQOFP02M2WXUCI/DXCHH1R2QJCJWZKAUOERYDOP3+5YZICDHWX54T7GIAU6XV9M/5FH39EBLVDITK85/3RKRZIB/6SRBFSKQVWPNG69WJGIZUYJYQNNKB8QXG5VCHRJ+OXITBWXYKFXBIKUIGE8AKUDL9OI2SR5I0HQ0AMLNCI9DASGHT6UQGZMVRKJC9/FVKLRQURLKMUL1AKWIDAQAB-----END RSA PUBLIC KEY-----但实际上并不正确:$ grep -v -- ----- < remote.pub  | base64 -d | dumpasn1 -Warning: Input is non-seekable, some functionality has been disabled.  0 264: SEQUENCE {  4 257:   [APPLICATION 2] {       :       Error: Spurious EOC in definite-length item.Error: Invalid data encountered at position 12: 4E 8A.$ openssl asn1parse -in remote.pub     0:d=0  hl=4 l= 264 cons: SEQUENCE              4:d=1  hl=4 l= 257 cons: appl [ 2 ]            8:d=2  hl=2 l=  49 prim: EOC                  59:d=2  hl=2 l=   8 prim: appl [ 11 ]          69:d=2  hl=2 l=  16 cons: appl [ 5 ]           71:d=3  hl=2 l=   0 prim: priv [ 19 ]       Error in encoding140590716953024:error:0D07209B:asn1 encoding routines:ASN1_get_object:too long:../crypto/asn1/asn1_lib.c:91:我不知道它是如何工作的,但我认为它应该只生成一个包含两个整数的序列,其中一个是 N,另一个是 E。我不确定为什么 dumpasn1 认为它编码了一个 [应用程序 2]但无论是 dumpasn1 还是 openssl 都认为生成的内容甚至是有效的 ASN.1。
查看完整描述

1 回答

?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

我试图重现你的问题,这对我有用......


考虑


package main


import "fmt"

import "crypto/rand"

import "crypto/rsa"

import "crypto/x509"

import "encoding/hex"

import (

    "encoding/pem"

    "log"

    "os"

)



func main() {

reader := rand.Reader

bitSize := 64



keypair, _:= rsa.GenerateKey(reader, bitSize)


fmt.Println("Public key ", &keypair.PublicKey)


pubkey_bytes := x509.MarshalPKCS1PublicKey(&keypair.PublicKey)


fmt.Println(hex.Dump(pubkey_bytes))


block := &pem.Block{

        Type: "MESSAGE",

        Bytes: pubkey_bytes ,

    }


    if err := pem.Encode(os.Stdout, block); err != nil {

        log.Fatal(err)

    }


}

运行时控制台会显示


Public key  &{14927333011981288097 65537}

00000000  30 10 02 09 00 cf 28 8a  49 37 1b 42 a1 02 03 01  |0.....(.I7.B....|

00000010  00 01                                             |..|


-----BEGIN MESSAGE-----

MBACCQDPKIpJNxtCoQIDAQAB

-----END MESSAGE-----

我使用https://asn1.io/asn1playground/


将此粘贴到架构中


World-Schema DEFINITIONS  ::= 

BEGIN

 RSAPublicKey ::= SEQUENCE {

          modulus           INTEGER,  -- n

          publicExponent    INTEGER   -- e

      }                                

END

点击编译


将此粘贴到解码中


30 10 02 09 00 cf 28 8a  49 37 1b 42 a1 02 03 01 00 01

结果是


RSAPublicKey SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 16

D0023E: Integer or enumerated value too long: 9; check field 'modulus' (type: INTEGER) of PDU #1 'RSAPublicKey'.

  modulus INTEGER: tag = [UNIVERSAL 2] primitive; length = 9

    2147483647

  publicExponent INTEGER: tag = [UNIVERSAL 2] primitive; length = 3

    65537

S0012E: Decoding of PDU #1 failed with the return code '10'.

我不确定他们为什么会发现错误,但 SEQUENCE 和 2 INTEGER 肯定存在(您实际上并不需要工具来查看它) 


查看完整回答
反对 回复 2022-05-10
  • 1 回答
  • 0 关注
  • 167 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

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

帮助反馈 APP下载

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

公众号

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