当前位置: 首页 > article >正文

【java】签名验签防篡改研究测试

上一篇文章写了接口安全通过一次性校验码和 时间戳可以防接口重放攻击、本篇将通过 signatrue签名模式进行研究性,知其所以然

说明本次实验是验证签名合法性该前端使用不安全加密,存在安全风险密钥在jsp中暴露

1、实现原理

2、前端

将 username 和 password 以及一个 秘密密钥 拼接在一起。例如:username + password + secretKey
使用 SHA-256 算法进行加密:通过 CryptoJS.SHA256 对拼接后的字符串进行加密。
生成 Base64 编码的签名:toString(CryptoJS.enc.Base64) 将加密结果转换成 Base64 编码便于传输

sign前端代码

<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sginnatrue</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>
</head>
<body>
<h2>签名验签sign测试</h2>
<form id="loginForm" method="POST" action="/sign">
    <label for="username">用户名:</label>
    <input type="text" id="username" name="username" required/><br/>

    <label for="password">密码:</label>
    <input type="password" id="password" name="password" required/><br/>

    <!-- 加入时间戳和Nonce -->
    <input type="hidden" name="timestamp" value="${timestamp}"/>
    <input type="hidden" name="nonce" value="${nonce}"/>
    <input type="hidden" name="signature" id="signature"/>

    <button type="submit">登录</button>
</form>
<br/>
 <p type="hidden" style="color:red">时间戳: ${timestamp}</p >
 <p type="hidden" style="color:red">一次性校验码: ${nonce}</p >


<script>
    // 生成签名的函数
    function generateSignature(username, password) {
        const secretKey = "yourSecretKey"; // 后端验证签名时用的密钥(应该由后端安全管理)
        const data = username + password + secretKey; // 拼接数据
        const signature = CryptoJS.SHA256(data).toString(CryptoJS.enc.Base64); // 生成签名(Base64 编码)
        return signature;
    }

    // 在表单提交前生成签名并填入表单
    document.getElementById('loginForm').onsubmit = function (event) {
        const username = document.getElementById('username').value;
        const password = document.getElementById('password').value;
        const signature = generateSignature(username, password);

        // 填充隐藏的签名字段
        document.getElementById('signature').value = signature;
    }
</script>
</body>
<br/>
<p style="color:red">${error}</p >
<p style="color:red">${success}</p >
</html>

3、后端

后端使用相同的拼接规则和密钥,重新生成签名并与前端发送的签名进行比对。如果一致,则验证通过

 @GetMapping("/sign")
    public String showNonce1(Model model) {
        long timestamp = System.currentTimeMillis();
        String nonce = UUID.randomUUID().toString();

        model.addAttribute("timestamp", timestamp);
        model.addAttribute("nonce", nonce);

        return "sign";
    }

    @PostMapping("/sign")
    public String handleLogin(@RequestParam String username,
                              @RequestParam String password,
                              @RequestParam String signature,
                              @RequestParam long timestamp,
                              @RequestParam String nonce,
                              Model model) throws NoSuchAlgorithmException {
        System.out.println("前端的签名:" + signature);
        String data = username + password + SECRET_KEY; // 数据拼接顺序与前端一致
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hashBytes = digest.digest(data.getBytes());
        //System.out.println(hashBytes);
        String hou = Base64.getEncoder().encodeToString(hashBytes);
        if(hou.equals(signature)){
            System.out.println("验签成功");
            model.addAttribute("success", "  欢迎用户   "+username+"  验签成功!");
            return "home";
        }else{
            System.out.println("验签失败");
            model.addAttribute("error", "  "+ username+" 验签失败!");
        }
        return "fail";
    }

验证测试

合法操作未篡改参数正常触发请求,响应正常

篡改username重放请求 提示username参数已被篡改,后端生成的签名与前端不一致则跳出失败界面


http://www.kler.cn/a/517016.html

相关文章:

  • 统计文本文件中单词频率的 Swift 与 Bash 实现详解
  • IDE提示:因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170
  • Docker Hub 全面解析及应对策略
  • 023:到底什么是感受野?
  • 微信小程序压缩图片
  • 从手动到智能:自动化三维激光扫描
  • 解决Python 在 Flask 开发模式下定时任务启动两次的问题
  • C# OpenCV机器视觉:交通标志识别
  • 【Uniapp-Vue3】下拉刷新
  • 最新-CentOS 7 基于1 Panel面板安装 JumpServer 堡垒机
  • maven打包springboot项目出现找不到符号错误
  • k8s 蓝绿发布、滚动发布、灰度发布
  • git和idea重新安装后提交异常
  • 【安当产品应用案例100集】034-安当KSP支持密评中存储数据的机密性和完整性
  • Stable Diffusion 图片背景完美替换
  • 游戏设备升级怎么选?RTX4070独显,ToDesk云电脑更具性价比
  • 仿 RabbitMQ 的消息队列3(实战项目)
  • 深度学习-93-大语言模型LLM之基于langchain的模型IO的输出解析
  • JAVA系统中Spring Boot 应用程序的配置文件:application.yml
  • 监控系统-zabbix
  • JAVA与数据结构-线性表
  • Git处理冲突详解
  • 如何把jupyter的一个.ipynb文件的多个单元格cell合并为1个cell
  • 深度学习之使用yolo网络训练kitti数据集:kitti数据集转换为VOC格式
  • RabbitMQ 仲裁队列 -- 解决 RabbitMQ 集群数据不同步的问题
  • 从Python的GIL谈谈Python多线程和多进程