142 lines
3.5 KiB
Go
142 lines
3.5 KiB
Go
package rsa
|
||
|
||
import (
|
||
"crypto/rsa"
|
||
"crypto/x509"
|
||
"encoding/pem"
|
||
"fmt"
|
||
)
|
||
|
||
type KeyFormat int
|
||
|
||
const (
|
||
RSA KeyFormat = iota
|
||
COMMON
|
||
)
|
||
|
||
// 将指定的私钥编码为PEM格式,如果不指定具体格式将使用RSA PRIVATE KEY(PKCS1)格式。
|
||
func EncodePrivateKey(key *rsa.PrivateKey, format ...KeyFormat) ([]byte, error) {
|
||
var block *pem.Block
|
||
switch append(format, RSA)[0] {
|
||
case COMMON:
|
||
key, err := x509.MarshalPKCS8PrivateKey(key)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("不支持的私钥格式,%w", err)
|
||
}
|
||
block = &pem.Block{
|
||
Type: "PRIVATE KEY",
|
||
Bytes: key,
|
||
}
|
||
case RSA:
|
||
fallthrough
|
||
default:
|
||
key := x509.MarshalPKCS1PrivateKey(key)
|
||
block = &pem.Block{
|
||
Type: "RSA PRIVATE KEY",
|
||
Bytes: key,
|
||
}
|
||
}
|
||
return pem.EncodeToMemory(block), nil
|
||
}
|
||
|
||
// 将指定的公钥编码为PEM格式,如果不指定具体格式将使用RSA PUBLIC KEY(PKCS1)格式。
|
||
func EncodePublicKey(key *rsa.PublicKey, format ...KeyFormat) ([]byte, error) {
|
||
var block *pem.Block
|
||
switch append(format, RSA)[0] {
|
||
case COMMON:
|
||
key, err := x509.MarshalPKIXPublicKey(key)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("不支持的公钥格式,%w", err)
|
||
}
|
||
block = &pem.Block{
|
||
Type: "PUBLIC KEY",
|
||
Bytes: key,
|
||
}
|
||
case RSA:
|
||
fallthrough
|
||
default:
|
||
key := x509.MarshalPKCS1PublicKey(key)
|
||
block = &pem.Block{
|
||
Type: "RSA PUBLIC KEY",
|
||
Bytes: key,
|
||
}
|
||
}
|
||
return pem.EncodeToMemory(block), nil
|
||
}
|
||
|
||
// 将给定的PEM证书内容解析为RSA私钥。
|
||
// 仅能读取PEM证书中的第一个私钥编码段。
|
||
func DecodePrivateKey(cert []byte) (*rsa.PrivateKey, error) {
|
||
var (
|
||
block *pem.Block
|
||
pemRestContent = cert
|
||
)
|
||
for {
|
||
block, pemRestContent = pem.Decode(pemRestContent)
|
||
if block == nil {
|
||
return nil, &KeyNotFoundError{}
|
||
}
|
||
if block.Type == "PRIVATE KEY" || block.Type == "RSA PRIVATE KEY" {
|
||
break
|
||
}
|
||
}
|
||
switch block.Type {
|
||
case "PRIVATE KEY":
|
||
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("不支持的私钥格式,%w", err)
|
||
}
|
||
pKey, ok := key.(*rsa.PrivateKey)
|
||
if !ok {
|
||
return nil, fmt.Errorf("提供的私钥不是RSA专用私钥,%w", err)
|
||
}
|
||
return pKey, nil
|
||
case "RSA PRIVATE KEY":
|
||
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("不支持的私钥格式,%w", err)
|
||
}
|
||
return key, nil
|
||
default:
|
||
return nil, fmt.Errorf("不支持的私钥格式或者私钥不存在,%s", block.Type)
|
||
}
|
||
}
|
||
|
||
// 将给定的PEM证书内容解析为RSA公钥。
|
||
// 仅能读取PEM证书中的第一个公钥编码段。
|
||
func DecodePublicKey(cert []byte) (*rsa.PublicKey, error) {
|
||
var (
|
||
block *pem.Block
|
||
pemRestContent = cert
|
||
)
|
||
for {
|
||
block, pemRestContent = pem.Decode(pemRestContent)
|
||
if block == nil {
|
||
return nil, &KeyNotFoundError{}
|
||
}
|
||
if block.Type == "PUBLIC KEY" || block.Type == "RSA PUBLIC KEY" {
|
||
break
|
||
}
|
||
}
|
||
switch block.Type {
|
||
case "PUBLIC KEY":
|
||
key, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("不支持的公钥格式,%w", err)
|
||
}
|
||
pKey, ok := key.(*rsa.PublicKey)
|
||
if !ok {
|
||
return nil, fmt.Errorf("提供的公钥不是RSA专用公钥,%w", err)
|
||
}
|
||
return pKey, nil
|
||
case "RSA PUBLIC KEY":
|
||
key, err := x509.ParsePKCS1PublicKey(block.Bytes)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("不支持的公钥格式,%w", err)
|
||
}
|
||
return key, nil
|
||
default:
|
||
return nil, fmt.Errorf("不支持的公钥格式或者公钥不存在,%s", block.Type)
|
||
}
|
||
}
|