golang RSA秘钥的解析方式总结

前言

加密、解密、签名、验签等操作总少不了对秘钥的处理,秘钥的存储格式决定了解析方式。在golang中关于RSA加密、解密、签名、验签的总结一文中提到的仅是针对的字符串类型的秘钥处理,本文中将对常见的几种RSA秘钥存储格式及解析方式做个总结。

解析方式

常见的几种秘钥存储格式有:字符串、证书文件、n/e参数等,以下介绍具体格式的解析处理。

1. 字符串格式

这是最常见的一种形式,通常RSA的秘钥都是以hex、base64编码后的字符串提供,如证书内的秘钥格式即是base64编码的字符串,然后添加前后的具体标识实现的。可以通过解码字符串,构建公钥/私钥。

注意:base64存在几种细节不同的编码格式,StdEncoding、URLEncoding、RawStdEncoding、RawURLEncoding,使用时还需要进一步确认秘钥具体编码格式,避免解码出错。以下未特殊说明的例子中均默认使用StdEncoding。

(1)公钥

直接hex、base64解码后调用x509.ParsePKIXPublicKey即可。

key, _ := hex.DecodeString(publicKeyStr)
publicKey, _ := x509.ParsePKIXPublicKey(key)
(2)私钥

由于RSA私钥存在PKCS1和PKCS8两种格式,因此解码后需要根据格式类型调用对应的方法即可。一般java使用pkcs8格式的私钥,其他语言使用pkcs1格式的私钥。使用时,记得确认下格式。

//解析pkcs1格式私钥
key, _ := base64.StdEncoding.DecodeString(pkcs1keyStr)
privateKey, _ := x509.ParsePKCS1PrivateKey(key)

//解析pkcs8格式私钥
key, _ := hex.DecodeString(pkcs8keyStr)
privateKey, err := x509.ParsePKCS8PrivateKey(key)

2. 证书文件格式

(1).pem、.cert、.cer、.crt

.pem、.cert、.cer、.crt等都是pem格式的文件,只是文件后缀不一。

PEM是Privacy Enhance Mail的缩写,PEM实质上是Base64编码的二进制内容(即对字符串格式私钥的文件化处理),再加上开始和结束行。

解析方式:读取文件,调用pem.Decode,然后按照base64解码,再解析成公钥/私钥。

key,_ := ioutil.ReadFile("pem_file_path")
block, _ := pem.Decode(key)
//解析成pkcs8格式私钥
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
//解析成pkcs1格式私钥
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
//解析成公钥
publicKey, _ := x509.ParsePKIXPublicKey(key)

(2).pkcs12、.pfx、.p12

.pkcs12、.pfx、.p12这些文件格式存储的是已加密后的内容,可以通过openssl转换成pem文件后进行处理。

提取密钥对:

openssl pkcs12 -in in.p12 -out out.pem -nodes

3. N,E参数

这种就是比较特殊的。

例如:login with apple keys的公钥就是这种格式的,需要根据n,e构造出公钥。

{
      "kty": "RSA",
      "kid": "eXaunmL",
      "use": "sig",
      "alg": "RS256",
      "n": "4dGQ7bQK8LgILOdLsYzfZjkEAoQeVC_aqyc8GC6RX7dq_KvRAQAWPvkam8VQv4GK5T4ogklEKEvj5ISBamdDNq1n52TpxQwI2EqxSk7I9fKPKhRt4F8-2yETlYvye-2s6NeWJim0KBtOVrk0gWvEDgd6WOqJl_yt5WBISvILNyVg1qAAM8JeX6dRPosahRVDjA52G2X-Tip84wqwyRpUlq2ybzcLh3zyhCitBOebiRWDQfG26EH9lTlJhll-p_Dg8vAXxJLIJ4SNLcqgFeZe4OfHLgdzMvxXZJnPp_VgmkcpUdRotazKZumj6dBPcXI_XID4Z4Z3OM1KrZPJNdUhxw",
      "e": "AQAB"
    }

使用时就需要,将N,E解析成big.Int格式,注意N、E的base64的具体编码格式:

pubN, _ := parse2bigInt(n)
pubE, _ := parse2bigInt(e)
pub = &rsa.PublicKey{
    N: pubN,
    E: int(pubE.Int64()),
}

// parse string to big.Int
func parse2bigInt(s string) (bi *big.Int, err error) {
    bi = &big.Int{}
    b, err := base64.RawURLEncoding.DecodeString(s)//此处使用的是RawURLEncoding
    if err != nil {
        return
    }
    bi.SetBytes(b)
    return
}

总结

以上是常见的几种密钥格式的解析方式,除了最后一种的指向性比较明确外,其他的解析方式还可以用于其他加密方式,因为说到底这些解析方式对应的就是秘钥存储的方式。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值