目录

  • 参考
  • 什么是加解密
  • 加密方式分类
    • 对称加密技术
    • 非对称加密技术(RSA加密算法)(数字证书)
      • 场景1:公钥加密,私钥解密
      • 场景2:秘钥加密:数字签名,公钥解密:验证签名
    • MD5(完全不考虑解密,也叫哈希算法,散列算法)
      • Postman
      • Jmeter
  • 接口签名sign原理
    • 什么是接口签名
    • 为什么做接口签名
  • 如何做接口签名
    • 对所有参数按key按ASCⅡ码做升序排序
    • 把参数名和参数值连接成字符串
    • 把申请到的appKey和appSecret连接到字符串的头部
    • 用时间戳连接到字符串的尾部,可以增加失效检测
    • 增加随机数nonstr防止重放攻击
    • 把上述字符串进行md5加密
  • 常见签名算法示例
    • 示例1

参考

B站讲的最好的接口加密解密以及接口签名sign原理

什么是加解密

加密:在网络上传输的原始数据(明文)经过加密算法加密后形成(密文)传输,防止被窃取
解密:将密文还原成原始数据

加密方式分类

对称式加密:对加密和解密使用同一个秘钥
非对称加密:非对称式加密需要两个秘钥(双钥),分别叫公钥和秘钥,这两把秘钥可以相互加解密。公钥公开的,不需要保密,而私钥是保密的。

对称加密技术

  • DES加密算法
  • AES加密算法
  • Base64算法

可以在https://www.bejson.com/enc/aesdes/体验
des和aes每次加密之后密文不一样,而Base64加密之后密文固定

非对称加密技术(RSA加密算法)(数字证书)

通过网站https://www.bejson.com/enc/rsa/在线生成公钥和私钥,并且可以进行公钥加密和私钥解密测试

场景1:公钥加密,私钥解密

两个用户:A和B,B有双钥;A想把一个数据报文通过加密方式发给B

场景2:秘钥加密:数字签名,公钥解密:验证签名

数字证书由来:由于公钥是公开的不安全,所以需要第三方的CA(数字证书颁发机构),对公钥加密,加密后的东西就叫数字证书
数字证书包括:B用户基本信息及B的公钥的信息。X509的标准

CA:双钥,通过私钥加密


Fiddler不能直接抓取https协议的数据报文,需要安装一个数字证书
https = http + ssl安全传输协议

ssl安全传输协议:安全套接层,NetScape研发

MD5(完全不考虑解密,也叫哈希算法,散列算法)

Postman

Jmeter


${__digest(MD5,admin,)}

接口签名sign原理

什么是接口签名

接口签名:使用用户名,密码,时间戳和所有的排过序之后的参数组合起来,再加密得到的字符串,字符串是唯一的有权访问接口的鉴权码
用户名:appKey
密码:appSecret

为什么做接口签名

  • 防伪装攻击
  • 防篡改攻击
  • 防重放攻击
  • 防数据泄露

保证访问者的合法性。保证参数不被修改,确保请求的唯一性

如何做接口签名

对所有参数按key按ASCⅡ码做升序排序

比如参数是?c=1&b=2&a=3
排序之后是a,b,c

把参数名和参数值连接成字符串

a=1&b=2&c=3

把申请到的appKey和appSecret连接到字符串的头部

appKey=admin&appSecret=123&a=1&b=2&c=3

用时间戳连接到字符串的尾部,可以增加失效检测

比如1分钟内有效

appKey=admin&appSecret=123&a=1&b=2&c=3&timestamp=1666757432136

增加随机数nonstr防止重放攻击

nonstr可以是随机数,最好是uuid

appKey=admin&appSecret=123&a=1&b=2&c=3&timestamp=1666757432136&nonstr=123123

把上述字符串进行md5加密

String str = "appKey=admin&appSecret=123&a=1&b=2&c=3&timestamp=1666757432136&nonstr=123123";
String sign = md5(str);

常见签名算法示例

示例1

签名算法
签名算法描述如下:
1.将请求参数按参数名升序排序;
2.按请求参数名及参数值相互连接组成一个字符串:…;
3.将应用密钥分别添加到以上请求参数串的头部和尾部:<请求参数字符串>;
4.对该字符串进行MD5(全部大写),MD5后的字符串即是这些请求参数对应的签名;
5.该签名值使用sign参数一起和其它请求参数一起发送给服务开放平台。

伪代码:

Map<String,Object> paramsMap = new ...; // 参数Set<String> keySet = paramsMap.keySet();
List<String> paramNames = new ArrayList<String>(keySet);
// 1.
Collections.sort(paramNames);StringBuilder paramNameValue = new StringBuilder();
// 2.
for (String paramName : paramNames) {paramNameValue.append(paramName).append(paramsMap.get(paramName));
}
// 3.
String source = secret + paramNameValue.toString() + secret;
// 4.
String sign = md5(source);
// 5.
paramsMap.put("sign",sign);

代码示例

import java.io.IOException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;import org.junit.Test;import com.alibaba.fastjson.JSON;import junit.framework.TestCase;public class PostTest extends TestCase {@Testpublic void testPost() throws IOException {String appKey = "xxx";String secret = "xxx";// 业务参数Map jsonMap = new HashMap();jsonMap.put("dicCode", "terminalType");String json = JSON.toJSONString(jsonMap);json = URLEncoder.encode(json, "utf-8");// 系统参数Map param = new HashMap();param.put("name", "dictionaryItem.list");param.put("version", "1.0");param.put("app_key", appKey);param.put("data", json);param.put("timestamp", getTime());param.put("format", "json");String sign = buildSign(param, secret);param.put("sign", sign);/*// 最终请求数据{"name":"dictionaryItem.list","version":"1.0","app_key":"test","data":"%7B%22dicCode%22%3A%22terminalType%22%7D","timestamp":"2021-12-15 10:25:02","format":"json","sign":"4B291FFFFDD6F0E3FB9708AC0F7AC334"}*/System.out.println("=====请求数据=====");String postJson = JSON.toJSONString(param);System.out.println(postJson);// contentType:application/json// postJson放到请求体中// 发送请求String resp = HttpRequest.post("https://xxx.net/api").body(postJson).execute().body();System.out.println(resp);/*响应结果:{"code":"0","data":[{"dicCode":"terminalType","isplay":1,"itemId":120,"itemName":"音柱/音箱","itemValue":"1","sort":1},{"dicCode":"terminalType","isplay":1,"itemId":121,"itemName":"AIO报警箱","itemValue":"2","sort":2},{"dicCode":"terminalType","isplay":1,"itemId":122,"itemName":"融媒体客服主机","itemValue":"3","sort":3},{"dicCode":"terminalType","isplay":1,"itemId":123,"itemName":"网络调音台","itemValue":"4","sort":4},{"dicCode":"terminalType","isplay":1,"itemId":124,"itemName":"云广播适配器","itemValue":"5","sort":5},{"dicCode":"terminalType","isplay":1,"itemId":125,"itemName":"音频编码器","itemValue":"6","sort":6},{"dicCode":"terminalType","isplay":1,"itemId":126,"itemName":"村级播控主机","itemValue":"7","sort":7},{"dicCode":"terminalType","isplay":1,"itemId":127,"itemName":"云话筒","itemValue":"8"},{"dicCode":"terminalType","isplay":1,"itemId":128,"itemName":"安卓手机客户端","itemValue":"9"},{"dicCode":"terminalType","isplay":1,"itemId":129,"itemName":"收扩机","itemValue":"10","sort":8}]}*/}/*** 构建签名** @param paramsMap*            参数* @param secret*            密钥* @return* @throws IOException*/public static String buildSign(Map<String, ?> paramsMap, String secret) throws IOException {Set<String> keySet = paramsMap.keySet();List<String> paramNames = new ArrayList<String>(keySet);Collections.sort(paramNames);StringBuilder paramNameValue = new StringBuilder();for (String paramName : paramNames) {paramNameValue.append(paramName).append(paramsMap.get(paramName));}String source = secret + paramNameValue.toString() + secret;return md5(source);}/*** 生成md5,全部大写** @param message* @return*/public static String md5(String message) {try {// 1 创建一个提供信息摘要算法的对象,初始化为md5算法对象MessageDigest md = MessageDigest.getInstance("MD5");// 2 将消息变成byte数组byte[] input = message.getBytes();// 3 计算后获得字节数组,这就是那128位了byte[] buff = md.digest(input);// 4 把数组每一字节(一个字节占八位)换成16进制连成md5字符串return byte2hex(buff);} catch (Exception e) {throw new RuntimeException(e);}}/*** 二进制转十六进制字符串** @param bytes* @return*/private static String byte2hex(byte[] bytes) {StringBuilder sign = new StringBuilder();for (int i = 0; i < bytes.length; i++) {String hex = Integer.toHexString(bytes[i] & 0xFF);if (hex.length() == 1) {sign.append("0");}sign.append(hex.toUpperCase());}return sign.toString();}/*** 十六进制字符串转二进制** @param hexString* @return*/private static byte[] hexStringToBytes(String hexString) {if (hexString == null || hexString.equals("")) {return null;}hexString = hexString.toUpperCase();int length = hexString.length() / 2;char[] hexChars = hexString.toCharArray();byte[] d = new byte[length];for (int i = 0; i < length; i++) {int pos = i * 2;d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));}return d;}/*** 二进制数据生成mp3音频文件** @param data     二进制数据* @param filePath 文件目录* @return*/public static String bytesToFile(byte[] data, String filePath) throws IOException {//方法一:直接生成文件String url = filePath + ".mp3";File file = new File(filePath);if (!file.exists()) {file.createNewFile();}FileOutputStream os = new FileOutputStream(file);os.write(data);//方法二:将二进制数据上传阿里云oss,生成文件//String url = "http://" + OSSFactory.build().uploadSuffix(data, ".mp3");return url;}public String getTime() {return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());}
}

WEB API 接口签名sign验证入门与实战相关推荐

  1. API接口签名生成算法和签名验证算法

    1.参考网上资料和书本资料,实现了API接口签名生成算法和签名验证算法. (1)参考资料:https://www.jianshu.com/p/d47da77b6419 (2)参考书籍:高级软件架构师教 ...

  2. 软件测试 接口测试 接口鉴权 token鉴权 Mock Server 接口加解密 接口签名sign

    文章目录 1 接口鉴权 1.1 cookie鉴权 1.2 session鉴权 1.3 token鉴权 1.4 Postman的鉴权方式 2 Mock Server 3 接口加解密 3.1 加密方式 3 ...

  3. API 接口签名验签

    目录 一.为什么需要 API 接口签名 二.API 接口签名验签实现机制 一.为什么需要 API 接口签名 对外开放的 API 接口都会面临一些安全问题,例如伪装攻击.篡改攻击.重放攻击以及数据信息泄 ...

  4. Web API接口开发和测试

    4.ASP.NET Web API的开发 上面我们定义了一般的Web API接口,以及实现相应的业务实现,如果我们需要创建Web API层,还需要构建一个Web API项目的. 创建好相应的项目后,可 ...

  5. Java API接口签名认证

    Java API接口签名认证 我们在进行程序开发的时候,一定会开发一些API接口,供他人访问.当然这些接口中有可能是开放的,也有可能是需要登录才能访问的,也就是需要Token鉴权成功后才可以访问的.那 ...

  6. 不使用jQuery对Web API接口POST,PUT,DELETE数据

    前些天,Insus.NET有演示Web API接口的操作: <怎样操作WebAPI接口(显示数据)>http://www.cnblogs.com/insus/p/5670401.html ...

  7. Spring Boot API 接口文档 Swagger 入门

    转载自 芋道 Spring Boot API 接口文档 Swagger 入门 摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/Swagger/ 「芋道源码」欢迎转 ...

  8. ASP.NET Web API 接口执行时间监控

    软件产品常常会出现这样的情况:产品性能因某些无法预料的瓶颈而受到干扰,导致程序的处理效率降低,性能得不到充分的发挥.如何快速有效地找到软件产品的性能瓶颈,则是我们感兴趣的内容之一. 在本文中,我将解释 ...

  9. rap2检测哪些接口在使用_使用RAP2和Mock.JS实现Web API接口的数据模拟和测试

    最近一直在思考如何对Web API的其接口数据进行独立开发的问题,随着Web API的越来越广泛应用,很多开发也要求前端后端分离,例如统一的Web API接口后,Winform团队.Web前端团队.微 ...

  10. 调用JShaman的Web API接口,实现JS代码加密。

    在NodeJS中,调用JShaman的Web API接口,实现JS代码加密. 同样的方法,也可把该功能集成到自己的产品或项目中,让自己也具备JS加密功能. 调用JShaman接口的源码非常简单: /* ...

最新文章

  1. Altium Designer 18 怎么导出CAD文件
  2. 最短公共子序列_最短公共超序列
  3. [leetcode]Generate Parentheses
  4. Linux练习(函数调用复制文件)
  5. 什么是IDS/IPS?
  6. VMWare虚拟机Linux系统忘记登录密码
  7. 蓝牙解码格式哪个最好_柏韵Pureaudio AirDSD Pro 串流播放解码前级
  8. Electron 使用 regedit 控制注册表(实现win文件右键菜单)
  9. 诺顿杀毒软件22010最新注册码
  10. Context是什么
  11. Google Chrome 66可以下载啦
  12. android 点击状态栏,“点击状态栏回到顶部”功能的消失原因和实现
  13. 面向订单生产型电子制造企业,如何快速响应客户?
  14. 2023年五一数学建模竞赛ABC题思路资料汇总贴
  15. TOP Network 2019年度回顾:积蓄力量,再创辉煌
  16. javafx 订单项目源码_终于找到一个JavaFx开发的东西,pdf阅读器。包括源代码
  17. 【发车优化】基于遗传算法的公交车调度排班优化的研究与实现附Matlab代码
  18. SecureCRT乱码的问题
  19. 编写一个求定积分的通用函数
  20. Flutter IOS 新建打包发布全流程 2023 版

热门文章

  1. mysql实现pr曲线_如何画PR curve (PR曲线)基于COCO格式数据集 在maskrcnn_benchmark中
  2. java bs和cs_BS与CS的区别和联系
  3. 毕业论文格式系列---1.论文公式编号
  4. 湘源控规计算土石方流程
  5. python 文本处理(分割)
  6. 谷歌恐龙游戏HTML,谷歌浏览器小恐龙游戏
  7. oracle 索引优化
  8. navicat for mysql Mac版 中文免安装
  9. 浅谈 Java 24个设计模式(23个GoF设计模式 + 简单工厂模式) 之 六个创建型模式...
  10. (学习笔记)图像处理——Retinex增强