ag_toolsbox/encryption/rsa/key.go

142 lines
3.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
}