123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- package rpc
- import (
- "context"
- "crypto"
- "crypto/hmac"
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha256"
- "crypto/x509"
- "encoding/base64"
- "encoding/hex"
- "encoding/json"
- "encoding/pem"
- "errors"
- "eta/eta_mini_crm_ht/utils"
- "fmt"
- "google.golang.org/grpc"
- "google.golang.org/grpc/credentials/insecure"
- "google.golang.org/grpc/metadata"
- "google.golang.org/protobuf/proto"
- "google.golang.org/protobuf/types/known/anypb"
- "io"
- "log"
- "os"
- "time"
- )
- const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
- type RpcService interface {
- GetPool(addr string) utils.ClientPool
- }
- type DefaultRpcClient struct {
- }
- func (d *DefaultRpcClient) WrapSign(request interface{}, doHandler func(ctx context.Context, req interface{}) error) {
- timestamp, nonce, sign, _ := d.signature(request, 16)
- fmt.Println(string(sign))
- ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(
- "nonce", nonce,
- "timestamp", fmt.Sprintf("%d", timestamp),
- "signature", sign,
- ))
- err := doHandler(ctx, request)
- if err != nil {
- utils.FileLog.Error("调用PRC服务失败:%v", err)
- }
- }
- func (d *DefaultRpcClient) getOptions() (opts []grpc.DialOption) {
- opts = make([]grpc.DialOption, 0)
- opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
- return opts
- }
- func (d *DefaultRpcClient) GetPool(addr string) utils.ClientPool {
- pool, err := utils.GetPoolInstance(addr, d.getOptions()...)
- if err != nil {
- log.Fatal(err)
- }
- return pool
- }
- // 生成签名
- func (d *DefaultRpcClient) generateSignature(req interface{}) string {
- message := req.(proto.Message)
- reqData, _ := anypb.New(message)
- reqBytes, _ := proto.Marshal(reqData)
- key := []byte("secret") // 秘钥应该保密
- mac := hmac.New(sha256.New, key)
- mac.Write(reqBytes)
- return hex.EncodeToString(mac.Sum(nil))
- }
- func (d *DefaultRpcClient) generateNonceStr(length int) (string, error) {
- result := make([]byte, length)
- n, err := io.ReadFull(rand.Reader, result)
- if err != nil {
- return "", err
- }
- for i := 0; i < n; i++ {
- result[i] = chars[int(result[i])%len(chars)]
- }
- return string(result), nil
- }
- type encryptedRequest struct {
- Message interface{} `json:"ciphertext"`
- Nonce string `json:"nonce"` // 添加随机字符串
- Timestamp int64 `json:"timestamp"` // 添加时间戳
- }
- func (d *DefaultRpcClient) signature(req interface{}, nonceLen int) (timestamp int64, nonceStr string, encodedData string, err error) {
- nonceStr, err = d.generateNonceStr(nonceLen)
- if err != nil {
- utils.FileLog.Error("随机字符串生成失败: %v", err)
- return
- }
- timestamp = time.Now().UnixMilli()
- // 构建加密后的数据结构
- encryptedStruct := encryptedRequest{
- Message: req,
- Nonce: nonceStr, // 添加随机字符串
- Timestamp: timestamp, // 添加时间戳
- }
- entryData, err := json.Marshal(encryptedStruct)
- if err != nil {
- utils.FileLog.Error("序列化加密后的数据失败: %v", err)
- return
- }
- // 使用私钥加密
- var privateKey *rsa.PrivateKey
- privateKey, err = d.parsePrivateKeyFromPEM()
- if err != nil {
- utils.FileLog.Error("私钥解析失败: %v", err)
- return
- }
- var encryptedData []byte
- hash := sha256.Sum256(entryData)
- // RSA加密
- encryptedData, err = rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash[:])
- if err != nil {
- utils.FileLog.Error("RSA加密失败: %v", err)
- return
- }
- // 编码加密后的数据
- encodedData = base64.StdEncoding.EncodeToString(encryptedData)
- return
- }
- // 解析RSA公钥
- func (d *DefaultRpcClient) parsePrivateKeyFromPEM() (privateKey *rsa.PrivateKey, err error) {
- pemBlock, err := os.ReadFile("./conf/rsa_private_key.pem")
- block, _ := pem.Decode(pemBlock)
- if block == nil {
- utils.FileLog.Error("公钥解析失败")
- return nil, errors.New("公钥解析失败")
- }
- privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- return nil, err
- }
- return
- }
|