Go语言x509包ParsePKIXPublicKey格式疑问及RSA公钥解析问题
解决RSA公钥解析错误及
ParsePKCS1PublicKey与ParsePKIXPublicKey的区别 首先,你的错误根源很明确:你用了错误的解析函数来匹配你的PEM公钥格式。你的PEM文件是-----BEGIN RSA PUBLIC KEY-----开头的PKCS#1格式,而你调用的x509.ParsePKIXPublicKey是用来解析PKCS#8格式(-----BEGIN PUBLIC KEY-----)公钥的,这就导致了ASN.1结构不匹配的报错。
先解答你关于PEM/DER解析的困惑
你不需要用什么der.Decode,你的第一步pem.Decode()是完全正确的。PEM本质就是DER格式的二进制数据加上Base64编码,再包裹头尾标注行,所以必须先用pem.Decode()把Base64解码后的原始DER字节提取出来,之后再用对应的x509解析函数去处理这个DER数据。
两个解析函数的核心区别
这两个函数针对的是不同标准的公钥格式,功能和返回值都有差异:
x509.ParsePKCS1PublicKey- 专门用于解析PKCS#1标准的RSA公钥,对应的PEM块头是
-----BEGIN RSA PUBLIC KEY----- - 解析成功后直接返回
*rsa.PublicKey类型,不需要额外的类型断言 - 只能处理RSA公钥,不支持其他类型(比如ECDSA)
- 专门用于解析PKCS#1标准的RSA公钥,对应的PEM块头是
x509.ParsePKIXPublicKey- 用于解析**PKIX标准(也就是PKCS#8)**的通用公钥,对应的PEM块头是
-----BEGIN PUBLIC KEY----- - 这种格式是通用的,能容纳RSA、ECDSA等多种类型的公钥,所以返回值是
interface{},需要你通过类型断言转换成对应的公钥类型(比如*rsa.PublicKey) - 兼容性更强,适合不知道公钥类型的场景
- 用于解析**PKIX标准(也就是PKCS#8)**的通用公钥,对应的PEM块头是
修正你的代码
把解析部分换成x509.ParsePKCS1PublicKey即可解决报错,修正后的完整代码如下:
package main import ( "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()) return // 记得添加return避免后续逻辑执行 } block, _ := pem.Decode([]byte(key)) if block == nil { fmt.Println("unable to decode publicKey to request") return } // 替换为PKCS#1对应的解析函数 pub, err := x509.ParsePKCS1PublicKey(block.Bytes) if err != nil { panic("failed to parse RSA encoded public key: " + err.Error()) } // 这里直接得到*rsa.PublicKey,无需类型断言 fmt.Println("pub is of type RSA:", pub) }
额外提示:兼容两种格式的写法
如果你的代码需要同时处理PKCS#1和PKCS#8格式的RSA公钥,可以通过判断PEM块的Type来选择解析函数:
switch block.Type { case "RSA PUBLIC KEY": pub, err := x509.ParsePKCS1PublicKey(block.Bytes) // 处理RSA公钥逻辑 case "PUBLIC KEY": pubIface, err := x509.ParsePKIXPublicKey(block.Bytes) pub, ok := pubIface.(*rsa.PublicKey) if !ok { panic("not an RSA public key") } // 处理RSA公钥逻辑 default: panic("unsupported public key format") }
内容的提问来源于stack exchange,提问作者Matheus Vinícius de Andrade
相关产品推荐
相关产品推荐

