signature_interceptor.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package rpc
  2. import (
  3. "context"
  4. "crypto"
  5. "crypto/rsa"
  6. "crypto/sha256"
  7. "crypto/x509"
  8. "encoding/base64"
  9. "encoding/json"
  10. "encoding/pem"
  11. "eta/eta_bridge/global"
  12. "fmt"
  13. "google.golang.org/grpc"
  14. "google.golang.org/grpc/codes"
  15. "google.golang.org/grpc/metadata"
  16. "google.golang.org/grpc/status"
  17. "io/ioutil"
  18. "strconv"
  19. )
  20. type encryptedRequest struct {
  21. Message interface{} `json:"ciphertext"`
  22. Nonce string `json:"nonce"` // 添加随机字符串
  23. Timestamp int64 `json:"timestamp"` // 添加时间戳
  24. }
  25. // 自定义拦截器
  26. func SignatureInterceptor(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
  27. // 获取签名
  28. md, ok := metadata.FromIncomingContext(ctx)
  29. if !ok {
  30. return nil, status.Errorf(codes.InvalidArgument, "metadata is missing")
  31. }
  32. // 从元数据中提取签名相关的信息
  33. nonceStr, ok := md["nonce"]
  34. if !ok || len(nonceStr) == 0 {
  35. return nil, status.Errorf(codes.InvalidArgument, "nonce不能为空")
  36. }
  37. timestampStr, ok := md["timestamp"]
  38. if !ok || len(timestampStr) == 0 {
  39. return nil, status.Errorf(codes.InvalidArgument, "时间戳不能为空")
  40. }
  41. timestamp, err := strconv.ParseInt(timestampStr[0], 10, 64)
  42. if err != nil {
  43. return nil, status.Errorf(codes.InvalidArgument, "无效的时间戳: %v", err)
  44. }
  45. signature, ok := md["signature"]
  46. if !ok || len(signature) == 0 {
  47. return nil, status.Errorf(codes.InvalidArgument, "签名信息不能为空")
  48. }
  49. decrytData := encryptedRequest{
  50. Message: req,
  51. Nonce: nonceStr[0], // 添加随机字符串
  52. Timestamp: timestamp, // 添加时间戳
  53. }
  54. dds, err := json.Marshal(decrytData)
  55. if err != nil {
  56. return nil, status.Errorf(codes.InvalidArgument, "json序列化失败")
  57. }
  58. publicKey, err := parsePublicKeyFromPEM([]byte(""))
  59. if err != nil {
  60. return nil, status.Errorf(codes.InvalidArgument, "公钥解析失败")
  61. }
  62. fmt.Println(string(dds))
  63. // 验证签名
  64. if !verifySignature(string(dds), signature[0], publicKey) {
  65. return nil, status.Errorf(codes.PermissionDenied, "invalid signature")
  66. }
  67. return handler(ctx, req)
  68. }
  69. // 验证签名
  70. func verifySignature(message, signature string, publicKey *rsa.PublicKey) bool {
  71. hash := sha256.Sum256([]byte(message))
  72. signatureBytes, err := base64.StdEncoding.DecodeString(signature)
  73. if err != nil {
  74. return false
  75. }
  76. err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hash[:], signatureBytes)
  77. return err == nil
  78. }
  79. func parsePublicKeyFromPEM(pemBytes []byte) (pubKey *rsa.PublicKey, err error) {
  80. pemBlock, err := ioutil.ReadFile("./config/rsa_public_key.pem")
  81. block, _ := pem.Decode(pemBlock)
  82. if block == nil {
  83. global.LOG.Error("公钥解析失败")
  84. }
  85. pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
  86. pubKey, ok := pubInterface.(*rsa.PublicKey)
  87. if !ok {
  88. global.LOG.Error("公钥解析失败")
  89. }
  90. if err != nil {
  91. return nil, err
  92. }
  93. return
  94. }