signature_interceptor.go 3.3 KB

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