完成游戏人生账号绑定、解绑、绑定信息的接口开发

This commit is contained in:
2025-06-09 16:27:18 +08:00
parent 5ead851b99
commit fee4d55725
27 changed files with 764 additions and 25 deletions

126
utility/rsa/rsa.go Normal file
View File

@ -0,0 +1,126 @@
package rsa
import (
"context"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"os"
"sync"
"github.com/gogf/gf/v2/frame/g"
)
type rsaClient struct {
publicKey *rsa.PublicKey
privateKey *rsa.PrivateKey
}
var (
instance *rsaClient
once sync.Once
)
// init 会在包初始化时自动调用,用于加载默认的 RSA 公钥和私钥。
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())
if err != nil {
panic("加载 RSA 密钥失败: " + err.Error())
}
})
}
// GetRsaClient 返回 RSA 客户端的单例实例。
//
// 通常用于执行加解密操作。
func GetRsaClient() *rsaClient {
return instance
}
// EncryptWithRsaPublicKey 使用加载的 RSA 公钥对原始数据进行加密。
//
// 参数:
// - plain: 待加密的明文数据。
//
// 返回值:
// - 加密后的密文数据。
// - 如果加密失败,则返回错误。
func (c *rsaClient) EncryptWithRsaPublicKey(plain []byte) ([]byte, error) {
if c.publicKey == nil {
return nil, errors.New("公钥未加载")
}
return rsa.EncryptPKCS1v15(rand.Reader, c.publicKey, plain)
}
// DecryptWithRsaPrivateKey 使用加载的 RSA 私钥对密文数据进行解密。
//
// 参数:
// - cipher: 加密后的密文数据。
//
// 返回值:
// - 解密后的明文数据。
// - 如果解密失败,则返回错误。
func (c *rsaClient) DecryptWithRsaPrivateKey(cipher []byte) ([]byte, error) {
if c.privateKey == nil {
return nil, errors.New("私钥未加载")
}
return rsa.DecryptPKCS1v15(rand.Reader, c.privateKey, cipher)
}
// loadKeys 从指定文件中加载 RSA 公钥和私钥。
//
// 参数:
// - publicKeyPath: 公钥 PEM 文件路径。
// - privateKeyPath: 私钥 PEM 文件路径。
//
// 返回值:
// - 成功返回 nil否则返回错误信息。
func (c *rsaClient) loadKeys(publicKeyPath, privateKeyPath string) error {
// 加载公钥
pubBytes, err := os.ReadFile(publicKeyPath)
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 公钥")
}
// 加载私钥
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 ok2 bool
if c.privateKey, ok2 = privKey.(*rsa.PrivateKey); !ok2 {
return errors.New("私钥不是 RSA 私钥")
}
return nil
}