Go语言Zero框架中实现在线签名与验签功能设计与实现

448 阅读3分钟

在GoZero框架中实现在线签名与验签功能,需要使用在线提供的API以及GoZero的服务框架进行集成。在线提供了一些接口用于数字签名和验签操作,具体操作步骤和代码设计可以参考以下内容。

image.png

1. 设计概述

在线提供了基于数字证书的签名与验签服务。整个流程分为以下几步:

  1. 签名:使用在线提供的私钥对数据进行签名,得到签名结果。
  2. 验签:使用在线提供的公钥对签名进行验证,确保数据的完整性和签名的合法性。

image.png 对于GoZero框架的集成,我们将主要进行以下设计:

  • 实现在线的签名与验签请求封装
  • 利用在线的API进行签名和验签操作
  • GoZero服务提供签名与验签的接口

2. 配置与依赖

首先,我们需要集成一些依赖库来处理与e签宝的API交互。

安装依赖

go get -u github.com/go-zero-zmq
go get -u github.com/levigross/grequests
go get -u github.com/sirupsen/logrus
  • grequests用于发送HTTP请求,与e签宝的API进行交互。
  • logrus用于日志记录。

3. e签宝API的基本实现

e签宝的签名和验签通常会涉及到调用e签宝的API。下面是基本的接口设计与调用。

3.1 配置文件(config.yaml)

e_sign:
  app_id: "your_app_id"
  app_secret: "your_app_secret"
  sign_url: "https://api.esign.cn/api/sign"
  verify_url: "https://api.esign.cn/api/verify"

配置文件中包含e签宝的app_idapp_secret,以及签名和验签的接口URL。

3.2 签名与验签实现

我们可以封装成两个方法,signDocument(用于签名)和verifySignature(用于验签)。

签名请求数据封装

package eSign

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/levigross/grequests"
	"log"
	"time"
)

type SignRequest struct {
	AppID      string `json:"app_id"`
	AppSecret  string `json:"app_secret"`
	Document   string `json:"document"`  // 文档内容(需签名的文档)
	SignMethod string `json:"sign_method"` // 签名方式
}

type SignResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Signature string `json:"signature"`  // 返回的签名
}

func SignDocument(request *SignRequest) (string, error) {
	// 构造签名请求
	apiUrl := "https://api.esign.cn/api/sign"
	reqBody, err := json.Marshal(request)
	if err != nil {
		log.Printf("Error marshalling request: %v", err)
		return "", err
	}

	resp, err := grequests.Post(apiUrl, &grequests.RequestOptions{
		JSON: request,
	})
	if err != nil {
		log.Printf("Error making API request: %v", err)
		return "", err
	}

	var res SignResponse
	if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
		log.Printf("Error decoding response: %v", err)
		return "", err
	}

	if res.Code != 0 {
		return "", fmt.Errorf("signing failed: %s", res.Message)
	}

	return res.Signature, nil
}

验签请求数据封装

package eSign

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/levigross/grequests"
	"log"
	"time"
)

type VerifyRequest struct {
	AppID     string `json:"app_id"`
	AppSecret string `json:"app_secret"`
	Document  string `json:"document"`
	Signature string `json:"signature"` // 待验证的签名
}

type VerifyResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	IsValid bool   `json:"is_valid"` // 是否验证通过
}

func VerifySignature(request *VerifyRequest) (bool, error) {
	// 构造验签请求
	apiUrl := "https://api.esign.cn/api/verify"
	reqBody, err := json.Marshal(request)
	if err != nil {
		log.Printf("Error marshalling request: %v", err)
		return false, err
	}

	resp, err := grequests.Post(apiUrl, &grequests.RequestOptions{
		JSON: request,
	})
	if err != nil {
		log.Printf("Error making API request: %v", err)
		return false, err
	}

	var res VerifyResponse
	if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
		log.Printf("Error decoding response: %v", err)
		return false, err
	}

	if res.Code != 0 {
		return false, fmt.Errorf("verification failed: %s", res.Message)
	}

	return res.IsValid, nil
}

4. GoZero服务层集成

在GoZero中实现一个服务提供签名和验签的API接口。

4.1 服务定义

package handler

import (
	"fmt"
	"github.com/tal-tech/go-zero/core/logx"
	"your_project/eSign"
	"your_project/service"
)

type SignHandler struct {
	logx.Logger
}

func (h *SignHandler) SignDocument(req *service.SignRequest) (*service.SignResponse, error) {
	signReq := &eSign.SignRequest{
		AppID:     "your_app_id",
		AppSecret: "your_app_secret",
		Document:  req.Document,
		SignMethod: "SHA256",
	}
	signature, err := eSign.SignDocument(signReq)
	if err != nil {
		return nil, fmt.Errorf("sign document failed: %v", err)
	}
	return &service.SignResponse{Signature: signature}, nil
}

func (h *SignHandler) VerifySignature(req *service.VerifyRequest) (*service.VerifyResponse, error) {
	verifyReq := &eSign.VerifyRequest{
		AppID:     "your_app_id",
		AppSecret: "your_app_secret",
		Document:  req.Document,
		Signature: req.Signature,
	}
	valid, err := eSign.VerifySignature(verifyReq)
	if err != nil {
		return nil, fmt.Errorf("verify signature failed: %v", err)
	}
	return &service.VerifyResponse{IsValid: valid}, nil
}

4.2 请求与响应模型(service)

package service

type SignRequest struct {
	Document string `json:"document"` // 待签名文档内容
}

type SignResponse struct {
	Signature string `json:"signature"` // 返回的签名
}

type VerifyRequest struct {
	Document  string `json:"document"`  // 文档内容
	Signature string `json:"signature"` // 签名
}

type VerifyResponse struct {
	IsValid bool `json:"is_valid"` // 验签结果
}

5. 启动服务

启动GoZero服务,监听请求。

go run main.go

总结

通过GoZero框架和e签宝API的结合,可以很方便地实现数字签名与验签的功能。我们通过封装e签宝的签名与验签API调用,将其集成到GoZero服务中,提供了简单易用的接口来完成签名与验签操作。