rpc.go 4.0 KB

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