调整 rsa 密钥解析函数
This commit is contained in:
@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user