|
@@ -2,49 +2,104 @@ package rpc
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
- "crypto/hmac"
|
|
|
+ "crypto"
|
|
|
+ "crypto/rsa"
|
|
|
"crypto/sha256"
|
|
|
+ "crypto/x509"
|
|
|
+ "encoding/base64"
|
|
|
+ "encoding/json"
|
|
|
+ "encoding/pem"
|
|
|
+ "errors"
|
|
|
+ "eta/eta_bridge/global"
|
|
|
+ "eta/eta_bridge/rpc/sso"
|
|
|
"fmt"
|
|
|
"google.golang.org/grpc"
|
|
|
"google.golang.org/grpc/codes"
|
|
|
"google.golang.org/grpc/metadata"
|
|
|
"google.golang.org/grpc/status"
|
|
|
- "google.golang.org/protobuf/proto"
|
|
|
- "google.golang.org/protobuf/types/known/anypb"
|
|
|
+ "strconv"
|
|
|
)
|
|
|
|
|
|
+type encryptedRequest struct {
|
|
|
+ Message []byte `json:"ciphertext"`
|
|
|
+ Nonce string `json:"nonce"` // 添加随机字符串
|
|
|
+ Timestamp int64 `json:"timestamp"` // 添加时间戳
|
|
|
+}
|
|
|
+
|
|
|
// 自定义拦截器
|
|
|
func SignatureInterceptor(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
|
|
+ // 获取签名
|
|
|
md, ok := metadata.FromIncomingContext(ctx)
|
|
|
if !ok {
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "metadata is missing")
|
|
|
}
|
|
|
|
|
|
- // 获取签名
|
|
|
- signature, ok := md["signature"]
|
|
|
- if !ok {
|
|
|
- return nil, status.Errorf(codes.Unauthenticated, "signature is missing")
|
|
|
+ // 从元数据中提取签名相关的信息
|
|
|
+ nonceStr, ok := md["nonce"]
|
|
|
+ if !ok || len(nonceStr) == 0 {
|
|
|
+ return nil, status.Errorf(codes.InvalidArgument, "nonce不能为空")
|
|
|
}
|
|
|
|
|
|
- // 验证签名
|
|
|
- if !verifySignature(req, signature[0]) {
|
|
|
- return nil, status.Errorf(codes.Unauthenticated, "invalid signature")
|
|
|
+ timestampStr, ok := md["timestamp"]
|
|
|
+ if !ok || len(timestampStr) == 0 {
|
|
|
+ return nil, status.Errorf(codes.InvalidArgument, "时间戳不能为空")
|
|
|
+ }
|
|
|
+ timestamp, err := strconv.ParseInt(timestampStr[0], 10, 64)
|
|
|
+ if err != nil {
|
|
|
+ return nil, status.Errorf(codes.InvalidArgument, "无效的时间戳: %v", err)
|
|
|
}
|
|
|
|
|
|
+ signature, ok := md["signature"]
|
|
|
+ if !ok || len(signature) == 0 {
|
|
|
+ return nil, status.Errorf(codes.InvalidArgument, "签名信息不能为空")
|
|
|
+ }
|
|
|
+ message := req.(*sso.LoginRequest)
|
|
|
+ str, err := json.Marshal(message)
|
|
|
+ decrytData := encryptedRequest{
|
|
|
+ Message: str,
|
|
|
+ Nonce: nonceStr[0], // 添加随机字符串
|
|
|
+ Timestamp: timestamp, // 添加时间戳
|
|
|
+ }
|
|
|
+ dds, err := json.Marshal(decrytData)
|
|
|
+ if err != nil {
|
|
|
+ return nil, status.Errorf(codes.InvalidArgument, "json序列化失败")
|
|
|
+ }
|
|
|
+ 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"))
|
|
|
+ if err != nil {
|
|
|
+ return nil, status.Errorf(codes.InvalidArgument, "公钥解析失败")
|
|
|
+ }
|
|
|
+ fmt.Println(dds)
|
|
|
+ // 验证签名
|
|
|
+ if !verifySignature(string(dds), signature[0], publicKey) {
|
|
|
+ return nil, status.Errorf(codes.PermissionDenied, "invalid signature")
|
|
|
+ }
|
|
|
return handler(ctx, req)
|
|
|
}
|
|
|
|
|
|
// 验证签名
|
|
|
-func verifySignature(req interface{}, signature string) bool {
|
|
|
- // 假设req是*pb.HelloRequest
|
|
|
- message := req.(proto.Message)
|
|
|
- reqData, _ := anypb.New(message)
|
|
|
- reqBytes, _ := proto.Marshal(reqData)
|
|
|
-
|
|
|
- key := []byte("secret-key") // 秘钥应该保密
|
|
|
- mac := hmac.New(sha256.New, key)
|
|
|
- mac.Write(reqBytes)
|
|
|
- expectedSignature := fmt.Sprintf("%x", mac.Sum(nil))
|
|
|
-
|
|
|
- return expectedSignature == signature
|
|
|
+func verifySignature(message, signature string, publicKey *rsa.PublicKey) bool {
|
|
|
+ hash := sha256.Sum256([]byte(message))
|
|
|
+ signatureBytes, err := base64.StdEncoding.DecodeString(signature)
|
|
|
+ if err != nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hash[:], signatureBytes)
|
|
|
+ return err == nil
|
|
|
+}
|
|
|
+
|
|
|
+func parsePublicKeyFromPEM(pemBytes []byte) (pubKey *rsa.PublicKey, err error) {
|
|
|
+ block, _ := pem.Decode(pemBytes)
|
|
|
+ if block == nil {
|
|
|
+ global.LOG.Error("公钥解析失败")
|
|
|
+ }
|
|
|
+ pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ pubKey, ok := pubInterface.(*rsa.PublicKey)
|
|
|
+ if !ok {
|
|
|
+ return nil, errors.New("RSA公钥格式错误")
|
|
|
+ }
|
|
|
+ return
|
|
|
}
|