doumianfeng6979 2019-02-19 15:01
浏览 484
已采纳

x509 Go软件包-ParsePKIXPublicKey是DER还是PEM?

I'm trying to get an object of rsa.PublicKey and I made these steps:

 ----BEGIN RSA PUBLIC KEY----
           ....
 ----END RSA PUBLIC KEY----
package main

import (
   "crypto/rand"
   "crypto/rsa"
   "crypto/x509"
   "encoding/pem"
   "fmt"
   "io/ioutil"
)

func main() {

 key, err := ioutil.ReadFile("./new_public.pem")
 if err != nil {
    fmt.Println(err.Error())
 }

 block, _ := pem.Decode([]byte(key))
 if block == nil {
    fmt.Println("unable to decode publicKey to request")
 }

 pub, err := x509.ParsePKIXPublicKey(block.Bytes)
 if err != nil {
     panic("failed to parse RSA encoded  public key" + err.Error())
 }

 switch pub := pub.(type) {
 case *rsa.PublicKey:
     fmt.Println("pub is of type RSA:", pub)
 default:
     panic("error")
 }

}

After this, when I try to x509.ParsePKIXPublicKey(block.Bytes) I get an error:

panic: failed to parse RSA encoded  public keyasn1: 
structure error: tags don't match (16 vs {class:0 tag:2 length:129 isCompound:false}) 
{
 optional:false 
 explicit:false 
 application:false 
 private:false 
 defaultValue:<nil> tag:<nil> 
 stringType:0 
 timeType:0 
 set:false 
 omitEmpty:false
} AlgorithmIdentifier @3

So, I read some blogs and documentations about DER and PEM formats, and they are differents ways to encode an certificate, basicaly one use base64 and other is just bytes.

In x509's package of Golang, the x509.ParsePKIXPublicKey says:

ParsePKIXPublicKey parses a DER-encoded public key. These values are typically found in PEM blocks with "BEGIN PUBLIC KEY"

And, in the example of this function use the pem.Decode(). I'm very confused about this because this should use pem.Decode or something like der.Decode() ?

Also, what's the real difference between x509.ParsePKCS1PublicKey() and x509.ParsePKIXPublicKey() ? Both do the same job to get a rsa.PublicKey ?

  • 写回答

2条回答 默认 最新

  • dongliao3742 2019-02-19 22:02
    关注

    The issue here is understanding the difference between x509.ParsePKCS1PublicKey (PKCS#1) and x509.ParsePKIXPublicKey (PKCS#8).

    Usually when the PEM header has the type as RSA PUBLIC KEY, it is referring to a PKCS#1 encoded RSA public key, which is defined in RFC 8017 (PKCS#1) as:

    RSAPublicKey ::= SEQUENCE {
         modulus           INTEGER,  -- n
         publicExponent    INTEGER   -- e
     }
    

    You haven't actually provided the body of your public key (it would be safe to do so), but it is a fair assumption that, if decoding the key using x509.ParsePKIXPublicKey failed, your key is likely in the above format (x509.ParsePKIXPublicKey uses PKCS#8 encoding).

    If this is the case, you should be able to get an rsa.PublicKey from the file using the following code (don't forget to add the error handling):

    rawPem, _ := ioutil.ReadFile("./public.key")
    pemBlock, _ := pem.Decode(rawPem)
    publicKey, _ := x509.ParsePKCS1PublicKey(pemBlock.Bytes)
    

    If this doesn't solve your problem, try pasting the key you have into this site to see what ASN.1 structure it uses. For reference, the key I used to test this is included here:

    -----BEGIN RSA PUBLIC KEY-----
    MIIBCgKCAQEApW1W9dnfdFF7FHrq6HPveR/9T+nM70yO7QOGytR0j/chMBJcJBjG
    hJOuKPFbkVyS+BE/4M8CojLgvz4ex82Re0sFa5TqnoWvuP5P4vktR6M5W53sTW3y
    gUnfF/oHcEmARQ1xKZdgVnlIfrdbpjecPyLi1Ng4HmhEfCFUOW64koxpb4XeH5O5
    q+vc/731ExVOYBU8Sl6kPdjpJuVjS3DHKAVgfVEhscXd3JDjDuMDT3w1IYNb5c2s
    wHE55q4Jnc1cr42jdynnkXzmuOGo2C6yD95kbBDLp7wSiBxaMA8gbRkzWJ99T+6l
    KsKG2zfndMF3jZW1v1wWiEbYRN07qbN0NQIDAQAB
    -----END RSA PUBLIC KEY-----
    

    ASN.1 Structure of reference RSA Public Key

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler