1.为什么要接口验签?

平常我们开发的时候,系统都会有个登录功能,登录的账号可能是公司内部的OA系统账号,通过登录得到的token,可以进行验证接口请求者的身份。

当我们提供一些接口给其它公司的时候,别人没有可以用于登录的账号,这个时候,想要对接口发起者进行身份的校验,比较合适的一种做法,就是利用appKey和md5来进行接口验签

2.验签思路

  1. 为某个接口调用者,生成 1个appKey加1个secret秘钥
  2. 调用者调用接口时,根据请求参数+appKey+secret秘钥,生成一个sign签名
  3. 调用者,请求接口的时候,把sign签名传递给服务端
  4. 服务端收到请求后,根据得到的appKey,去数据库中查询对应的secure秘钥
  5. 服务端,把sign签名从参数中移除,和客户端做一样的事情,根据请求参数+appKey+secret秘钥,也计算一个sign签名
  6. 服务端把自己计算得出的sign签名,和接口调用者传递过来的sign签名进行比较,如果一致,则证明这个接口的调用者,是合法的身份

3.具体做法

3.1.创建存储秘钥的表

CREATE TABLE `co_key` (`id` int(11) NOT NULL AUTO_INCREMENT,`app_key` varchar(30) DEFAULT NULL COMMENT 'app_key',`secret` varchar(50) DEFAULT NULL COMMENT '秘钥',`desc` varchar(50) DEFAULT NULL COMMENT '描述',`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='秘钥表';

在表中,插入一条记录,代表新增1个合法的接口调用者,appKey和秘钥,随便是什么字符串都可以

INSERT INTO `core_business1`.`co_key`(`id`, `app_key`, `secret`, `desc`, `create_time`) VALUES (1, 'test', '1385632C36126942', '测试', '2022-05-22 19:57:26');

3.2.创建实体类

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("co_key")
@ApiModel(value="Key对象", description="")
public class Key implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Integer id;@ApiModelProperty(value = "app_key")private String appKey;@ApiModelProperty(value = "秘钥")private String secret;@ApiModelProperty(value = "描述")private LocalDateTime desc;@ApiModelProperty(value = "创建时间")private LocalDateTime createTime;}

3.3.创建请求的参数类

@Data
public class TestSecretSaveParam extends BaseSecretParam {@ApiModelProperty("昵称")private String nickName;@ApiModelProperty("名称")private String name;@ApiModelProperty("年龄")private Integer age;@ApiModelProperty("城市")private String city;@ApiModelProperty("爱好")private String hobby;
}

3.4.编写验签逻辑

public interface IKeyService extends IService<Key> {void validateSign(TestSecretSaveParam param);}
@Slf4j
@Service
public class KeyServiceImpl extends ServiceImpl<KeyMapper, Key> implements IKeyService {@Overridepublic void validateSign(TestSecretSaveParam param) {//appKeyString appKey = param.getAppKey();//参数中的signString paramSign = param.getSign();//找这个appKey对应的秘钥String secret = getSecret(appKey);//计算signString sign = getSign(param, secret);if(!paramSign.equals(sign)){throw new BusinessException("md5不匹配");}}private String getSign(TestSecretSaveParam param, String secret) {//先移除secret参数param.setSign(null);//序列化成字符串。String jsonStr = JSON.toJSONString(param);//利用fastJson的反序列化,来进行排序JSONObject jsonObject = JSON.parseObject(jsonStr, Feature.OrderedField);//获取排序后的参数String sortedStr = jsonObject.toString();//加上秘钥String waitMd5 = sortedStr + secret;//md5加密String md5 = SecureUtil.md5(waitMd5);log.info("md5加密的内容:{},期望匹配的md5: {}", waitMd5, md5);return md5;}private String getSecret(String appKey){LambdaQueryWrapper<Key> wr = new LambdaQueryWrapper<>();//只查询秘钥wr.select(Key::getSecret);//根据appKey匹配wr.eq(Key::getAppKey, appKey);List<Key> list = baseMapper.selectList(wr);if(CollectionUtil.isEmpty(list)){throw new BusinessException(String.format("appKey %s 不存在", appKey));}if(list.size() > 1){throw new BusinessException("1个appKey找到2条秘钥");}Key key = list.get(0);//秘钥String secret = key.getSecret();return secret;}}

3.5.编写测试接口

    @ApiOperation("测试秘钥访问接口")@PostMapping("testSecretSaveLog")public ApiResult<String> testSecretSaveLog(@Validated @RequestBody TestSecretSaveParam param){keyService.validateSign(param);return ApiResult.ok("成功访问接口");}

3.6.测试

假设现在我们的请求参数是:

{"city": "广州","age": 20,"appKey": "test","name": "张三","hobby": "羽毛球","nickName": "三儿"
}

测试的时候,我们要怎么样得到签名呢?

第一步,参数按照key排序,排序后:


{"age": 20,"appKey": "test","city": "广州","hobby": "羽毛球","name": "张三","nickName": "三儿"
}

第二步,参数去除空格

{"age":20,"appKey":"test","city":"广州","hobby":"羽毛球","name":"张三","nickName":"三儿"}

第三步:参数末尾,加上sign的值:

{"age":20,"appKey":"test","city":"广州","hobby":"羽毛球","name":"张三","nickName":"三儿"}1385632C36126942

第四步:找个md5在线加密的网站,比如:https://md5jiami.bmcx.com,对自己的内容进行加密,注意取32位小写的那个,生成结果:78ec94f7846ea999ea29bc9bdc911f36

第五步,把sign签名,加入到我们最开始的请求参数中,如:

{"city": "广州","age": 20,"appKey": "test","name": "张三","hobby": "羽毛球","nickName": "三儿","sign": "78ec94f7846ea999ea29bc9bdc911f36"
}

测试结果:

基于appKey和md5算法的接口验签方式相关推荐

  1. Openssl ECC椭圆曲线算法 - 密钥/签名/验签/加密/解密/SM2密文 - 序列化反序列化导出导入 - C源码

    . . . . 废话不多说,本代码继承自另外一位讲解Openssl ECC椭圆曲线算法大佬的源代码:https://blog.csdn.net/scuyxi/article/details/59182 ...

  2. 国家医保移动支付国密算法SM2签名验签、SM4加解密DLL

    国家医保移动支付国密算法SM2签名验签.SM4加解密DLL 支持医保移动支付(国家统一版), 已知省份有广西.贵州.安徽.河北.黑龙江.湖南.吉林.江苏.四川.新疆等各地方. DLL,非.net开发, ...

  3. php pkcs7签名验签算法,OpenSSL 签名验签接口调用及测试

    OpenSSL 签名验签接口调用及测试 概述 项目中我们经常会遇到开发签名.验签功能.签名.验签是可信赖网络的一个重要功能.因此,我记录了OpenSSL 签名验签接口调用及测试. 相关测试代码 bas ...

  4. 企业微信回调接口验签

    文章目录 一.企业微信配置参数 二.验签 三.企业微信客户联系回调 四.相关工具类 企业微信提供了回调接口,允许企业服务商和企业应用接收到企业微信的事件通知和用户操作通知.在接收到回调通知时,需要进行 ...

  5. aop java 接口_Spring AOP实现接口验签

    因项目需要与外部对接,为保证接口的安全性需要使用aop进行方法的验签; 在调用方法的时候,校验外部传入的参数进行验证, 验证通过就执行被调用的方法,验证失败返回错误信息: 不是所有的方法都需要进行验签 ...

  6. C++ 使用OpenSSL 基于SHA1摘要的RSA签名及验签 与Java平台互通

    文章目录 准备 C++ Java RSASignature.java RSAEncrypt.java Base64.java 准备 配置OpenSSL环境 配置VS2015环境 生成公私秘钥 然后你们 ...

  7. php支付接口验签,银联支付接口开发php版

    官方文档:https://open.unionpay.com/ajweb/help/file/techFile?productId=1 api辅助工具:https://open.unionpay.co ...

  8. Java简单的对外接口验签

    对外接口,需要校验一下是否有相应权限,简单的一个小代码. res加密util: /*** @description: AES加密解密工具* @author:mic* @create: **/ publ ...

  9. ECDSA算法加解密验签

    前段时间,因为公司业务需求研究了一下加密验签算法,找到了网上一位大佬的研究代码参考 Java中加密算法介绍及其实现 - 枫飘雪落 - 博客园 在大佬的研究中说明中找到了我需要的算法介绍,但是下载了大佬 ...

最新文章

  1. 1.httpClient和ScrollView
  2. 错误fatal error: curl/curl.h: No such file or directory解决方案
  3. HDU 5792 World is Exploding(树状数组+离散化)
  4. 任务调度(三)——Timer的替代品ScheduledExecutorService简介
  5. 计算矩阵中全1子矩阵的个数
  6. Mongo DB命令简介
  7. hnu 暑期实训之愚人节的礼物
  8. 简单java程序_简单的Java程序
  9. 兴业银行研发中心笔试题_2021国考笔试成绩即将发布,面试重点考什么?
  10. 利用ArcGIS Pro进行时空数据挖掘和可视化呈现
  11. 如何手动合成年度夜间灯光影像
  12. okhttp post php,Android OkHttp 结合php 多图片上传实例
  13. webp格式图片如何简单快速转换成JPG、PNG格式
  14. Word2Vec模型增量训练
  15. AMD显卡怎么设置玩游戏更流畅
  16. 机器学习预测股票涨跌
  17. mdadm chuck_面向所有人的Python-Chuck博士提供的14小时免费Python课程
  18. 保研面试/考研复试高等数学问题整理
  19. opencv 车牌识别---新能源车牌处理(二值化后按位取反)
  20. Android 解决OutOfMemory,从避免内存溢出开始

热门文章

  1. tightvnc由于目标计算机积极拒绝,TightVNC的连接可以作出,因为目标机器积极地拒绝它...
  2. JS - Web端的点九图
  3. 2016 总结:一个应届生的互联网名企逐梦记
  4. CRM为外贸企业拓展商机提供原动力
  5. 启动腾讯软件出现 应用程序无法启动并行配置不正确 解决
  6. 电商直播+元宇宙,虚拟人结合虚拟场景直播打开双十一营销新局面
  7. 关于ECMA、ECMAScript、TC39、ES、Stage等概念的科普
  8. 学编程到底需要什么计算机基础知识?
  9. 新年快乐---关于C# 的小笑话
  10. javascript原型链初识