调整 rsa 密钥解析函数

This commit is contained in:
2025-06-16 10:19:38 +08:00
parent 4c491f5c2e
commit 2903be6223
19 changed files with 235 additions and 96 deletions

View File

@ -7,10 +7,11 @@ import (
"crypto/x509"
"encoding/pem"
"errors"
"os"
"sync"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"os"
"strings"
"sync"
)
type rsaClient struct {
@ -28,7 +29,7 @@ func init() {
ctx := context.Background()
once.Do(func() {
instance = &rsaClient{}
err := instance.loadKeys(g.Config().MustGet(ctx, "rsa.publickey").String(), g.Config().MustGet(ctx, "rsa.privatekey").String())
err := instance.loadKeys(g.Config().MustGet(ctx, "gamelife.rsaKey").String())
if err != nil {
panic("加载 RSA 密钥失败: " + err.Error())
}
@ -80,47 +81,94 @@ func (c *rsaClient) DecryptWithRsaPrivateKey(cipher []byte) ([]byte, error) {
//
// 返回值:
// - 成功返回 nil否则返回错误信息。
func (c *rsaClient) loadKeys(publicKeyPath, privateKeyPath string) error {
// 加载公钥
pubBytes, err := os.ReadFile(publicKeyPath)
func (c *rsaClient) loadKeys(keyFilePath string) error {
// 读取密钥文件
keyBytes, err := os.ReadFile(keyFilePath)
if err != nil {
return err
}
pubBlock, _ := pem.Decode(pubBytes)
if pubBlock == nil {
return errors.New("无法解析公钥 PEM 文件")
}
pubKey, err := x509.ParsePKIXPublicKey(pubBlock.Bytes)
if err != nil {
return err
}
var ok bool
if c.publicKey, ok = pubKey.(*rsa.PublicKey); !ok {
return errors.New("公钥不是 RSA 公钥")
return fmt.Errorf("读取密钥文件失败: %w", err)
}
// 加载私钥
privBytes, err := os.ReadFile(privateKeyPath)
if err != nil {
return err
}
privBlock, _ := pem.Decode(privBytes)
if privBlock == nil {
return errors.New("无法解析私钥 PEM 文件")
}
// 尝试解析 PKCS#8 格式
privKey, err := x509.ParsePKCS8PrivateKey(privBlock.Bytes)
if err != nil {
// 回退尝试 PKCS#1 格式
privKey, err = x509.ParsePKCS1PrivateKey(privBlock.Bytes)
if err != nil {
return errors.New("解析私钥失败: 既不是 PKCS#8 也不是 PKCS#1 格式")
var pubFound, privFound bool
rest := keyBytes
for {
var block *pem.Block
block, rest = pem.Decode(rest)
if block == nil {
break
}
// 转换为小写以匹配你的密钥格式
blockTypeLower := strings.ToLower(block.Type)
switch blockTypeLower {
case "rsa public key":
// 尝试解析 PKCS#1 格式的公钥
pubKey, err := x509.ParsePKCS1PublicKey(block.Bytes)
if err != nil {
// 尝试 PKIX 格式(兼容性处理)
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return fmt.Errorf("无法解析 RSA 公钥: %w", err)
}
var ok bool
if c.publicKey, ok = pub.(*rsa.PublicKey); !ok {
return errors.New("解析的公钥不是 RSA 公钥")
}
} else {
c.publicKey = pubKey
}
pubFound = true
case "rsa private key":
// 解析 PKCS#1 格式的私钥
privKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return fmt.Errorf("无法解析 RSA 私钥: %w", err)
}
c.privateKey = privKey
privFound = true
default:
// 忽略未知的 PEM 块
continue
}
}
var ok2 bool
if c.privateKey, ok2 = privKey.(*rsa.PrivateKey); !ok2 {
return errors.New("私钥不是 RSA 钥")
if !pubFound {
return errors.New("未找到有效的 RSA 钥")
}
if !privFound {
return errors.New("未找到有效的 RSA 私钥")
}
return nil
}
// EncryptWithPublicKey 使用公钥加密数据
func (c *rsaClient) EncryptWithPublicKey(plaintext []byte) ([]byte, error) {
if c.publicKey == nil {
return nil, errors.New("公钥未加载")
}
// 使用 OAEP 填充进行加密
ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, c.publicKey, plaintext)
if err != nil {
return nil, fmt.Errorf("公钥加密失败: %w", err)
}
return ciphertext, nil
}
// DecryptWithPrivateKey 使用私钥解密数据
func (c *rsaClient) DecryptWithPrivateKey(ciphertext []byte) ([]byte, error) {
if c.privateKey == nil {
return nil, errors.New("私钥未加载")
}
// 使用 OAEP 填充进行解密
plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, c.privateKey, ciphertext)
if err != nil {
return nil, fmt.Errorf("私钥解密失败: %w", err)
}
return plaintext, nil
}