Skip to content
vue使用HMAC-SHA256签名算法

在 Vue.js 应用中生成签名算法通常涉及以下几个步骤:

  • 收集数据:获取需要签名的数据。
  • 整理数据:根据协议或需求对数据进行排序、拼接、编码等处理。
  • 计算签名:使用密钥和算法(如 HMAC-SHA256)计算签名。
  • 附加签名:将签名附加到请求中(如 HTTP Header、URL 参数、Request Body)。
  • 常用的签名算法有 HMAC、RSA 等,下面主要介绍如何在 Vue.js 中使用 HMAC-SHA256 生成签名。

在 Vue.js 中生成 HMAC-SHA256 签名

安装

js
npm install crypto-js

vue2 使用方式

js
<template>
  <div>
    <h1>签名示例</h1>
    <button @click="generateSignature">生成签名</button>
    <p>签名:{{ signature }}</p>
  </div>
</template>

<script>
import CryptoJS from "crypto-js";

export default {
  data() {
    return {
      signature: "",
    };
  },
  methods: {
    generateSignature() {
      // 示例数据
      const data = {
        message: "Hello, World!",
        timestamp: 111,
      };

      // 密钥(在真实场景中,应保密,随便写都行,一般是后端返回给前端)
      const secretKey = "111";

      // 将数据排序并拼接成字符串
      const sortedData = Object.keys(data)
        .sort()
        .map((key) => `${key}=${data[key]}`)
        .join("&");

      // 计算 HMAC-SHA256 签名
      const hash = CryptoJS.HmacSHA256(sortedData, secretKey);

      // 转换成字符串格式
      this.signature = CryptoJS.enc.Hex.stringify(hash);
    },
  },
};
</script>

<style scoped>
h1 {
  font-size: 1.5em;
}
</style>

解释

  • 数据排序与拼接:Object.keys(data).sort().map(...).join('&'); 对数据的键进行排序,并拼接成 key=value&key=value 的格式。
  • 计算 HMAC-SHA256:CryptoJS.HmacSHA256(sortedData, secretKey) 生成 HMAC-SHA256 签名。
  • 转换成字符串:CryptoJS.enc.Hex.stringify(hash); 将签名转换为十六进制字符串。

实际应用 在实际应用中,签名生成往往需要考虑以下几点:

  • 安全性:密钥应保密,不应暴露在前端代码中。通常在后端生成签名,前端只负责发送数据。
  • 编码处理:有些 API 要求对数据进行 URL 编码或其他特定格式处理。
  • 时间戳或随机数:为了防止重放攻击,通常需要在数据中包含时间戳或随机数。

完整 HTTP 请求示例

js
<template>
  <div>
    <h1>签名请求示例</h1>
    <button @click="sendSignedRequest">发送签名请求</button>
    <p>响应:{{ response }}</p>
  </div>
</template>

<script>
import axios from 'axios';
import CryptoJS from 'crypto-js';

export default {
  data() {
    return {
      response: ''
    };
  },
  methods: {
    generateSignature(data, secretKey) {
      // 将数据排序并拼接成字符串
      const sortedData = Object.keys(data)
        .sort()
        .map(key => `${key}=${data[key]}`)
        .join('&');

      // 计算 HMAC-SHA256 签名
      const hash = CryptoJS.HmacSHA256(sortedData, secretKey);

      // 转换成字符串格式
      return CryptoJS.enc.Hex.stringify(hash);
    },
    async sendSignedRequest() {
      const data = {
        message: 'Hello, API!',
        timestamp: Math.floor(Date.now() / 1000)
      };

      const secretKey = 'your_secret_key';
      const signature = this.generateSignature(data, secretKey);

      try {
        const response = await axios.post('https://api.example.com/data', data, {
          headers: {
            'X-Signature': signature
          }
        });
        this.response = response.data;
      } catch (error) {
        this.response = error.message;
      }
    }
  }
};
</script>

<style scoped>
h1 {
  font-size: 1.5em;
}
</style>

HTML 生成签名算法的示例代码

js
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>签名示例</title>
    <style>
      h1 {
        font-size: 1.5em;
      }
      .container {
        padding: 20px;
      }
      .button {
        display: inline-block;
        margin: 10px 0;
        padding: 10px 20px;
        background-color: #007bff;
        color: #fff;
        border: none;
        cursor: pointer;
        border-radius: 5px;
      }
      .button:hover {
        background-color: #0056b3;
      }
      .signature {
        font-family: monospace;
        margin-top: 10px;
      }
    </style>
    <!-- 引入 CryptoJS 库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
  </head>
  <body>
    <div class="container">
      <h1>签名示例</h1>
      <button class="button" onclick="generateSignature()">生成签名</button>
      <p class="signature">签名:<span id="signature"></span></p>
    </div>

    <script>
      function generateSignature() {
        // 示例数据
        const data = {
          message: "Hello, World!",
          timestamp: Math.floor(Date.now() / 1000),
        };

        // 密钥(在真实场景中,应保密)
        const secretKey = "your_secret_key";

        // 将数据排序并拼接成字符串
        const sortedData = Object.keys(data)
          .sort()
          .map((key) => `${key}=${data[key]}`)
          .join("&");

        // 计算 HMAC-SHA256 签名
        const hash = CryptoJS.HmacSHA256(sortedData, secretKey);

        // 转换成字符串格式
        const signature = CryptoJS.enc.Hex.stringify(hash);

        // 显示签名
        document.getElementById("signature").textContent = signature;
      }
    </script>
  </body>
</html>