百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Java,安全,Web/互联网HTTP通信,JSON HmacSHA256签名、验证签名

toyiye 2024-08-10 21:26 7 浏览 0 评论

说明

Web/互联网HTTP通信过程中,往往对数据的安全性、完整性构成挑战,以下是通过对JSON数据签名和验证签名的方式来保证传输数据的完整性。

签名的过程:

参考:数字签名

代码

package com.what21.apps.json.sign;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import javax.crypto.spec.SecretKeySpec;

public class JSONSignTools {

    /**
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static String hmacSHA256(String data, String key) throws Exception {
        String algorithm = "HmacSHA256";
        javax.crypto.Mac mac = javax.crypto.Mac.getInstance(algorithm);
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), algorithm);
        mac.init(secret_key);
        byte[] array = mac.doFinal(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    /**
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static String hmacMD5(String data, String key) throws Exception {
        String algorithm = "HmacMD5";
        javax.crypto.Mac mac = javax.crypto.Mac.getInstance(algorithm);
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), algorithm);
        mac.init(secret_key);
        byte[] array = mac.doFinal(data.getBytes("UTF-8"));
        return byteArrayToHexString(array).toUpperCase();
    }

    /**
     * byte数组转换为HexString
     *
     * @param b
     * @return
     */
    public static String byteArrayToHexString(byte[] b) {
        StringBuffer sb = new StringBuffer(b.length * 2);
        for (int i = 0; i < b.length; i++) {
            int v = b[i] & 0xff;
            if (v < 16) {
                sb.append('0');
            }
            sb.append(Integer.toHexString(v));
        }
        return sb.toString();
    }

    /**
     * @param srcJson
     * @param signName
     * @param signKey
     * @return
     * @throws Exception
     */
    public static String jsonSignByHmacMD5(String srcJson, String signName, String signKey) throws Exception {
        srcJson = JsonSorted.sorted(srcJson);
        // System.out.println(srcJson);
        JSONObject jsonObject = JSON.parseObject(srcJson);
        jsonObject.put(signName, hmacMD5(srcJson, signKey));
        return JsonSorted.sorted(jsonObject.toJSONString());
    }

    /**
     * @param signJson
     * @param signName
     * @param signKey
     * @return
     * @throws Exception
     */
    public static boolean verifyJsonSignByHmacMD5(String signJson, String signName, String signKey) throws Exception {
        JSONObject jsonObject = JSON.parseObject(signJson);
        String signValue = jsonObject.getString(signName);
        if (signValue == null) {
            return false;
        }
        jsonObject.remove(signName);
        String targetJson = JsonSorted.sorted(jsonObject.toJSONString());
        String signCode = hmacMD5(targetJson, signKey);
        if (signValue.equalsIgnoreCase(signCode)) {
            return true;
        }
        return false;
    }


    /**
     * @param srcJson
     * @param signName
     * @param signKey
     * @return
     * @throws Exception
     */
    public static String jsonSignByHmacSHA256(String srcJson, String signName, String signKey) throws Exception {
        srcJson = JsonSorted.sorted(srcJson);
        JSONObject jsonObject = JSON.parseObject(srcJson);
        jsonObject.put(signName, hmacSHA256(srcJson, signKey));
        return JsonSorted.sorted(jsonObject.toJSONString());
    }

    /**
     * @param signJson
     * @param signName
     * @param signKey
     * @return
     * @throws Exception
     */
    public static boolean verifyJsonSignByHmacSHA256(String signJson, String signName, String signKey) throws Exception {
        JSONObject jsonObject = JSON.parseObject(signJson);
        String signValue = jsonObject.getString(signName);
        if (signValue == null) {
            return false;
        }
        jsonObject.remove(signName);
        String targetJson = JsonSorted.sorted(jsonObject.toJSONString());
        String signCode = hmacSHA256(targetJson, signKey);
        if (signValue.equalsIgnoreCase(signCode)) {
            return true;
        }
        return false;
    }

}
package com.what21.apps.json.sign;

import com.google.gson.*;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

public class JsonSorted {

    /**
     * 定义比较规则
     *
     * @return
     */
    private static Comparator<String> getComparator() {
        return (s1, s2) -> s1.compareTo(s2);
    }

    /**
     * 排序
     *
     * @param e
     */
    private static void sort(JsonElement e) {
        if (e.isJsonNull() || e.isJsonPrimitive()) {
            return;
        }
        if (e.isJsonArray()) {
            JsonArray a = e.getAsJsonArray();
            Iterator<JsonElement> it = a.iterator();
            it.forEachRemaining(i -> sort(i));
            return;
        }
        if (e.isJsonObject()) {
            Map<String, JsonElement> tm = new TreeMap<>(getComparator());
            for (Map.Entry<String, JsonElement> en : e.getAsJsonObject().entrySet()) {
                tm.put(en.getKey(), en.getValue());
            }
            String key;
            JsonElement val;
            for (Map.Entry<String, JsonElement> en : tm.entrySet()) {
                key = en.getKey();
                val = en.getValue();
                e.getAsJsonObject().remove(key);
                e.getAsJsonObject().add(key, val);
                sort(val);
            }
        }
    }

    /**
     * 根据json key排序
     *
     * @param json
     * @return
     */
    public static String sorted(String json) {
        // Gson gson = new GsonBuilder().setPrettyPrinting().create();
        Gson gson = new GsonBuilder().create();
        JsonParser p = new JsonParser();
        JsonElement e = p.parse(json);
        sort(e);
        return gson.toJson(e);
    }

}
package com.what21.apps.json.sign;

import com.google.gson.Gson;
import lombok.Data;

import java.util.Arrays;
import java.util.List;

public class JSONSignToolsTest {

    @Data
    static class Person {
        private Integer id;
        private String name;
        private Integer age;
        private List<String> item;
    }

    public static void main(String[] args) throws Exception {
        Person person = new Person();
        person.setId(1);
        person.setName("孙叔敖");
        person.setAge(12);
        person.setItem(Arrays.asList("11", "22", "33"));
        Gson gson = new Gson();
        String srcJson = gson.toJson(person);
        String signName = "sign";
        String signKey = "communicationKey";
        System.out.println("源JSON:" + srcJson);
        // 生成签名
        String hmacMD5SignJson = JSONSignTools.jsonSignByHmacMD5(srcJson,signName,signKey);
        System.out.println("HmacMD5.签名JSON: " + hmacMD5SignJson);
        String hmacSHA256SignJson = JSONSignTools.jsonSignByHmacSHA256(srcJson,signName,signKey);
        System.out.println("HmacSHA256.签名JSON: " + hmacSHA256SignJson);
        // 验证签名
        boolean result1 = JSONSignTools.verifyJsonSignByHmacMD5(hmacMD5SignJson,signName,signKey);
        System.out.println("HmacMD5.签名JSON验证: " + result1);
        boolean result2 = JSONSignTools.verifyJsonSignByHmacSHA256(hmacSHA256SignJson,signName,signKey);
        System.out.println("HmacSHA256.签名JSON验证: " + result2);
    }

}

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码