MD5散列算法验签

MD5验签是一种用于验证数据完整性和防止数据篡改的安全机制。MD5(Message-Digest Algorithm 5)是一种散列算法,它可以将任意长度的消息转换为一个固定长度(通常是128位)的散列值,这个散列值通常被称为“摘要”或“哈希”。
在验签过程中,MD5通常结合私有密钥使用,流程如下:

1.生成签名

将请求头和请求体合并,并去除签名字段(如sign),因为签名本身不应该参与计算。
对合并后的字符串进行排序,通常是按照参数名的字典序排序。
将排序后的字符串与预先设定的密钥(私钥)拼接在一起。
使用MD5算法对拼接后的字符串进行散列,生成一个固定的长度的散列值,这就是签名。

2.发送签名

将生成的签名附加到请求中,通常作为一个参数(如sign)发送给服务器。

3.服务器验证签名

服务器收到请求后,重复上述签名生成的步骤,使用相同的密钥和数据重新计算签名。
比较计算出的签名与请求中携带的签名是否一致。
如果两个签名一致,说明数据在传输过程中没有被篡改;如果不一致,则可能数据已被篡改,或者请求不是来自可信的源。
MD5验签的优点在于其简单和快速,但是MD5算法已经被证明存在碰撞攻击的弱点,即不同的原始数据可能产生相同的MD5散列值。因此,在安全性要求较高的场景中,更推荐使用SHA-256等更安全的散列算法进行验签。

4.简单案列

下面通过一个简单案列来模拟验签流程,首先定义一个实体接收参数

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * 这只是一个测试DTO
 */
@Data
public class TestStuDTO {
    @ApiModelProperty(value = "姓名")
    private String name;

    @ApiModelProperty(value = "年龄")
    private String age;

    @ApiModelProperty(value = "性别")
    private String sex;

    @ApiModelProperty(value = "地址")
    private String address;

    @ApiModelProperty(value = "电话")
    private String phone;

    @ApiModelProperty(value = "key")
    private String secretKey;

    @ApiModelProperty(value = "MD5签名字符串(长度32)")
    private String sign;
}

为了方便数据处理,Maven中用到以下两个依赖

        <!-- hutool工具包 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.7</version>
        </dependency>

        <!--  fastjson序列化  -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.0</version>
        </dependency>

编写一个接口简单模拟接收客户端数据验签

    @ApiOperation(value = "这只是一个验签测试接口")
    @PostMapping("/push-test")
    public boolean pushTest(@RequestBody TestStuDTO testStuDTO) {
        log.info(StrUtil.format("开始调用【测试接口】,接收参数:{}", JSONUtil.toJsonStr(testStuDTO)));
        /** 可根据实际规定是否需要对原始数据排序拼接或其他处理 这里只做最基本演示
         ---------------------
         ---------------------
         **/
        JsonMapper jsonMapper = new JsonMapper();
        HashMap map = jsonMapper.convertValue(testStuDTO, HashMap.class);
        map.remove("sign");  // 移除客户端签名
        try {
            String jsonStr = jsonMapper.writeValueAsString(map);
            String sign = MD5.create().digestHex(jsonStr, StandardCharsets.UTF_8);
            System.out.println("服务端产生sign:"+sign);
            if (!sign.equals(testStuDTO.getSign())) {  // 验签 如果服务端和客户端的签名不一致 则认为数据不正确
                return false;
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return true;
    }

最后只需要判断客户端传过来的Sign和服务端对数据处理后创建的Sign是否一致即可
注意:在真实环境中,需要客户端和服务端约定好签名的方式(原始数据是否排序处理、大小写处理、拼接密钥处理等)

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值