API签名算法,go后端生成签名和验证签名

这次主要的实践内容是 API接口签名设计,以下是一些关键的步骤: 给前端分配一个 secretKey ,

以下是对这段代码的解读及教程:

一、代码功能概述 这段代码定义了一个名为getDataTest的函数,其主要功能是生成特定参数的签名,然后使用这些参数发送请求,并在请求成功后打印响应结果。签名的生成过程包括对给定参数进行排序、拼接特定字符串并使用 MD5 算法进行哈希计算。

前端使用第三方的库

import crypto from 'crypto-js';

二、代码详细解读

1const getDataTest = () => { 2 const secretKey = 'helloWorld'; 3 const params = { 4 v: '1.0', 5 page: "1", 6 pageSize: "10", 7 }; 8 9 // 获取当前时间戳 10 const timestamp = "1724383084118"; 11 12 // 对参数进行 key 排序 13 const sortedParams = {}; 14 Object.keys(params) 15 .sort() 16 .forEach(key => { 17 sortedParams[key] = params[key]; 18 }); 19 20 // 生成签名 21 const signatureData = Object.keys(sortedParams) 22 .map(key => `${key}${sortedParams[key]}`) 23 .join('') + `secretKey${secretKey}timestamp${timestamp}`; 24 // 使用 MD5 算法进行哈希计算 25 const hashedString = crypto.MD5(signatureData).toString(); 26 27 // 发送请求,(可以自己封装Axios) 28 getData({ 29 ...sortedParams, 30 timestamp, 31 sign: hashedString, 32 } 33 ).then((res) => { 34 console.log(res); 35 }); 36 37}

3.调整参数和密钥 根据实际需求,可以调整params对象中的参数值以及secretKey的值。同时,如果时间戳不是固定的,可以使用动态生成时间戳的方法替代硬编码的时间戳。

4.处理请求结果 根据实际业务需求,对请求成功后的响应结果进行进一步的处理。在代码中,目前只是简单地打印了响应结果,可以根据具体情况进行更复杂的操作。

请注意,代码中的时间戳和密钥等可能需要根据实际情况进行动态生成和管理,以确保安全性和有效性。同时,确保getData函数的正确性和稳定性,以便成功发送请求并处理响应。

5.后端部分,以下是对这段代码的解读及使用教程:

1package main 2 3import ( 4 "crypto/md5" 5 "encoding/hex" 6 "fmt" 7 "sort" 8 "strconv" 9 "strings" 10 "time" 11 12 "github.com/gin-gonic/gin" 13) 14 15// generateSignature 根据给定参数和密钥生成签名 16func generateSignature(params map[string]interface{}, secretKey string, timestamp int64) string { 17 // 移除签名和时间戳参数 18 delete(params, "sign") 19 delete(params, "timestamp") 20 21 // 获取参数的键列表并排序 22 keys := make([]string, 0, len(params)) 23 for k := range params { 24 keys = append(keys, k) 25 } 26 sort.Strings(keys) 27 28 var signatureBuilder strings.Builder 29 // 拼接参数键值和密钥、时间戳 30 for _, key := range keys { 31 signatureBuilder.WriteString(key) 32 signatureBuilder.WriteString(params[key].(string)) 33 } 34 signatureBuilder.WriteString("secretKey" + secretKey) 35 signatureBuilder.WriteString("timestamp" + strconv.FormatInt(timestamp, 10)) 36 37 fmt.Printf("|generateSignature: %s\n", signatureBuilder.String()) 38 // 计算 MD5 哈希并返回十六进制编码的签名 39 hash := md5.Sum([]byte(signatureBuilder.String())) 40 return hex.EncodeToString(hash[:]) 41} 42 43// ValidateSignature 封装签名验证逻辑 44func ValidateSignature(c *gin.Context, secretKey string) bool { 45 receivedParams := make(map[string]interface{}) 46 if err := c.Bind(&receivedParams); err != nil { 47 c.JSON(400, gin.H{"error": "Invalid request"}) 48 return false 49 } 50 51 receivedTimestamp, err := strconv.ParseInt(receivedParams["timestamp"].(string), 10, 64) 52 if err != nil { 53 c.JSON(400, gin.H{"error": "Invalid timestamp"}) 54 return false 55 } 56 57 currentTime := time.Now().UnixNano() / int64(time.Millisecond) 58 if currentTime-receivedTimestamp > 120000 { // 允许 2 分钟的时间差 59 c.JSON(400, gin.H{"error": "Timestamp expired"}) 60 return false 61 } 62 63 receivedSignature := receivedParams["sign"] 64 65 expectedSignature := generateSignature(receivedParams, secretKey, receivedTimestamp) 66 fmt.Print(expectedSignature) 67 // 验证签名是否一致 68 if receivedSignature != expectedSignature { 69 return false 70 } else { 71 return true 72 } 73} 74 75func main() { 76 r := gin.Default() 77 r.GET("/order", func(c *gin.Context) { 78 secretKey := "helloWorld" 79 if !ValidateSignature(c, secretKey) { 80 return 81 } 82 83 c.JSON(200, gin.H{"message": "Request is valid", "secretKey": secretKey}) 84 }) 85 r.Run() // 监听并在 0.0.0.0:8080 上启动服务 86} 87 88

客户端在发送请求时,需要在请求参数中包含正确的时间戳和签名。签名可以按照以下步骤生成: 确定请求参数,不包括sign和timestamp参数。 对参数的键进行排序。 将排序后的键值对拼接起来,再拼接上密钥和时间戳。 使用 MD5 算法计算哈希值,并将其转换为十六进制编码作为签名。

请注意,在实际应用中,可以根据具体需求对时间戳的有效期、密钥的生成和管理等进行进一步的优化和调整,以提高安全性和稳定性。

点赞
收藏

评论区

加载中...

相关推荐

springMVC笔记系列(8)——RequestParam注解

前面的文章介绍过注解@PathVariable,它能够为Rest风格的URL用占位符的方式传递一个参数,但是这个参数并不是真正意义上的请求参数。请求参数怎么处理是本文的主要内容。SpringMVC通过分析处理方法的签名,将HTTP请求信息绑定到处理方法的相应人参中。SpringMVC对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任

开放API接口签名验证,让你的接口从此不再裸奔

接口安全问题请求身份是否合法?请求参数是否被篡改?请求是否唯一?AccessKey&SecretKey(开放平台)请求身份为开发者分配AccessKey(开发者标识,确保唯一)和SecretKey(用于接口加密,确保不易被穷举,生成算法不易被猜测)。防止篡改参数签名1.按照请求参数名的字母升序排列非空请求参数(包含AccessK

unity android V1签名

unity2018版本默认签名会进行V1V2签名。如果只想进行V1签名的话可以进行以下操作。1.调整为gradle打包2.publishingsettings里面选择customgradletemplate,3.在gradle配置里面加入下述代码  !(https://oscimg.oschina.net/oscnet/up

OpenSSL和Python实现RSA Key公钥加密私钥解密

基于非对称算法的RSAKey主要有两个用途,数字签名和验证(私钥签名,公钥验证),以及非对称加解密(公钥加密,私钥解密)。本文提供一个基于OpenSSL和Python进行非对称加解密的例子。1\.OpenSSL实现非对称加解密1.1生成私钥,并导出公钥生成2048bit的PEM格式的RSAKey:Key.pem$openssl

Linux CA

CA(CertificateAuthority)证书颁发机构主要负责证书的颁发、管理以及归档和吊销。证书内包含了拥有证书者的姓名、地址、电子邮件帐号、公钥、证书有效期、发放证书的CA、CA的数字签名等信息。证书主要有三大功能:加密、签名、身份验证。1.什么是CA认证?CA认证,即CA认证机构,为电子签名相关各方提供真实性、可靠性验证

Node.js 中使用 ECDSA 签名遇到的坑

文/Fenying最近有个朋友问我关于Node.js下使用ECDSA的问题,主要是使用Node.js的Crypto模块无法校验网络传输过来的签名结果。在踩坑无数后,终于搞清楚了原因。坑0x00:签名输出格式在排除了证书、消息不一致的可能之后,我开始对比使用Node.js签名的结果与网络传输过来的签