我试图获取rsa.PublicKey的对象,并执行了以下步骤:
----BEGIN RSA PUBLIC KEY----
....
----END RSA PUBLIC KEY----
Run Code Online (Sandbox Code Playgroud)
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")
}
Run Code Online (Sandbox Code Playgroud)
}
此后,当我尝试x509.ParsePKIXPublicKey(block.Bytes)出现错误时:
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
Run Code Online (Sandbox Code Playgroud)
因此,我阅读了一些有关DER和PEM格式的博客和文档,它们是编码证书的不同方法,基本上一个使用base64,而另一个仅使用字节。
在Golang的x509软件包中,x509.ParsePKIXPublicKey表示:
ParsePKIXPublicKey parses a DER-encoded public key. These values are typically found in PEM blocks with "BEGIN PUBLIC KEY"
并且,在此函数的示例中,使用pem.Decode()。我对此很困惑,因为这应该使用pem.Decode或类似的东西der.Decode()?
另外,x509.ParsePKCS1PublicKey()和之间的真正区别是x509.ParsePKIXPublicKey()什么?两者都完成了rsa.PublicKey的相同工作?
这里的问题是理解x509.ParsePKCS1PublicKey(PKCS#1)和x509.ParsePKIXPublicKey(PKCS#8)之间的区别。
通常,当 PEM 标头的类型为 时RSA PUBLIC KEY,它指的是 PKCS#1 编码的 RSA 公钥,它在RFC 8017 (PKCS#1) 中定义为:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
Run Code Online (Sandbox Code Playgroud)
您实际上还没有提供您的公钥的主体(这样做是安全的),但可以合理地假设,如果使用密钥解码x509.ParsePKIXPublicKey失败,您的密钥可能采用上述格式(x509.ParsePKIXPublicKey使用 PKCS#8编码)。
如果是这种情况,您应该能够rsa.PublicKey使用以下代码从文件中获取一个(不要忘记添加错误处理):
rawPem, _ := ioutil.ReadFile("./public.key")
pemBlock, _ := pem.Decode(rawPem)
publicKey, _ := x509.ParsePKCS1PublicKey(pemBlock.Bytes)
Run Code Online (Sandbox Code Playgroud)
如果这不能解决您的问题,请尝试将您拥有的密钥粘贴到该站点以查看它使用的 ASN.1 结构。作为参考,我用来测试的密钥包含在此处:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEApW1W9dnfdFF7FHrq6HPveR/9T+nM70yO7QOGytR0j/chMBJcJBjG
hJOuKPFbkVyS+BE/4M8CojLgvz4ex82Re0sFa5TqnoWvuP5P4vktR6M5W53sTW3y
gUnfF/oHcEmARQ1xKZdgVnlIfrdbpjecPyLi1Ng4HmhEfCFUOW64koxpb4XeH5O5
q+vc/731ExVOYBU8Sl6kPdjpJuVjS3DHKAVgfVEhscXd3JDjDuMDT3w1IYNb5c2s
wHE55q4Jnc1cr42jdynnkXzmuOGo2C6yD95kbBDLp7wSiBxaMA8gbRkzWJ99T+6l
KsKG2zfndMF3jZW1v1wWiEbYRN07qbN0NQIDAQAB
-----END RSA PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)