rpc.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package rpc
  2. import (
  3. "context"
  4. "crypto"
  5. "crypto/hmac"
  6. "crypto/rand"
  7. "crypto/rsa"
  8. "crypto/sha256"
  9. "crypto/x509"
  10. "encoding/base64"
  11. "encoding/hex"
  12. "encoding/json"
  13. "encoding/pem"
  14. "errors"
  15. "eta/eta_mini_crm_ht/utils"
  16. "fmt"
  17. "google.golang.org/grpc"
  18. "google.golang.org/grpc/credentials/insecure"
  19. "google.golang.org/grpc/metadata"
  20. "google.golang.org/protobuf/proto"
  21. "google.golang.org/protobuf/types/known/anypb"
  22. "io"
  23. "log"
  24. "os"
  25. "time"
  26. )
  27. const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  28. type RpcService interface {
  29. GetPool(addr string) utils.ClientPool
  30. }
  31. type DefaultRpcClient struct {
  32. }
  33. func (d *DefaultRpcClient) WrapSign(request interface{}, doHandler func(ctx context.Context, req interface{}) error) {
  34. timestamp, nonce, sign, _ := d.signature(request, 16)
  35. fmt.Println(string(sign))
  36. ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(
  37. "nonce", nonce,
  38. "timestamp", fmt.Sprintf("%d", timestamp),
  39. "signature", sign,
  40. ))
  41. err := doHandler(ctx, request)
  42. if err != nil {
  43. utils.FileLog.Error("调用PRC服务失败:%v", err)
  44. }
  45. }
  46. func (d *DefaultRpcClient) getOptions() (opts []grpc.DialOption) {
  47. opts = make([]grpc.DialOption, 0)
  48. opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
  49. return opts
  50. }
  51. func (d *DefaultRpcClient) GetPool(addr string) utils.ClientPool {
  52. pool, err := utils.GetPoolInstance(addr, d.getOptions()...)
  53. if err != nil {
  54. log.Fatal(err)
  55. }
  56. return pool
  57. }
  58. // 生成签名
  59. func (d *DefaultRpcClient) generateSignature(req interface{}) string {
  60. message := req.(proto.Message)
  61. reqData, _ := anypb.New(message)
  62. reqBytes, _ := proto.Marshal(reqData)
  63. key := []byte("secret") // 秘钥应该保密
  64. mac := hmac.New(sha256.New, key)
  65. mac.Write(reqBytes)
  66. return hex.EncodeToString(mac.Sum(nil))
  67. }
  68. func (d *DefaultRpcClient) generateNonceStr(length int) (string, error) {
  69. result := make([]byte, length)
  70. n, err := io.ReadFull(rand.Reader, result)
  71. if err != nil {
  72. return "", err
  73. }
  74. for i := 0; i < n; i++ {
  75. result[i] = chars[int(result[i])%len(chars)]
  76. }
  77. return string(result), nil
  78. }
  79. type encryptedRequest struct {
  80. Message interface{} `json:"ciphertext"`
  81. Nonce string `json:"nonce"` // 添加随机字符串
  82. Timestamp int64 `json:"timestamp"` // 添加时间戳
  83. }
  84. func (d *DefaultRpcClient) signature(req interface{}, nonceLen int) (timestamp int64, nonceStr string, encodedData string, err error) {
  85. nonceStr, err = d.generateNonceStr(nonceLen)
  86. if err != nil {
  87. utils.FileLog.Error("随机字符串生成失败: %v", err)
  88. return
  89. }
  90. timestamp = time.Now().UnixMilli()
  91. // 构建加密后的数据结构
  92. encryptedStruct := encryptedRequest{
  93. Message: req,
  94. Nonce: nonceStr, // 添加随机字符串
  95. Timestamp: timestamp, // 添加时间戳
  96. }
  97. entryData, err := json.Marshal(encryptedStruct)
  98. if err != nil {
  99. utils.FileLog.Error("序列化加密后的数据失败: %v", err)
  100. return
  101. }
  102. // 使用私钥加密
  103. var privateKey *rsa.PrivateKey
  104. privateKey, err = d.parsePrivateKeyFromPEM()
  105. if err != nil {
  106. utils.FileLog.Error("私钥解析失败: %v", err)
  107. return
  108. }
  109. var encryptedData []byte
  110. hash := sha256.Sum256(entryData)
  111. // RSA加密
  112. encryptedData, err = rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash[:])
  113. if err != nil {
  114. utils.FileLog.Error("RSA加密失败: %v", err)
  115. return
  116. }
  117. // 编码加密后的数据
  118. encodedData = base64.StdEncoding.EncodeToString(encryptedData)
  119. return
  120. }
  121. // 解析RSA公钥
  122. func (d *DefaultRpcClient) parsePrivateKeyFromPEM() (privateKey *rsa.PrivateKey, err error) {
  123. pemBlock, err := os.ReadFile("./conf/rsa_private_key.pem")
  124. block, _ := pem.Decode(pemBlock)
  125. if block == nil {
  126. utils.FileLog.Error("公钥解析失败")
  127. return nil, errors.New("公钥解析失败")
  128. }
  129. privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
  130. if err != nil {
  131. return nil, err
  132. }
  133. return
  134. }