Java接口签名和验签

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.util.*; public class Signature { /**
* 签名
* @param object
* @param key
* @return
* @throws Exception
*/
public static String getSign(Object object,String key) throws Exception {
Map<String, String> map = objectToMap(object);
return getSign(map,key);
} private static Map<String, String> objectToMap(Object object) {
Map<String,String> map = new HashMap<>();
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
map.put(field.getName(), String.valueOf(field.get(object)));
}catch (Exception e) {
e.printStackTrace();
}
}
return map;
} /**
* 签名
* @param map
* @param key
* @return
* @throws Exception
*/
public static String getSign(Map<String,String> map,String key) throws Exception{
ArrayList<String> list = new ArrayList<String>();
for(Map.Entry<String,String> entry:map.entrySet()){
if(entry.getValue() != null && StringUtils.isNotBlank(entry.getValue().toString()) && !"null".equals(entry.getValue())
&& !"class".equals(entry.getKey()) && !"data".equals(entry.getKey())){ //空字符串 entry.getValue()!=""){
list.add(entry.getKey() + "=" + entry.getValue() + "&");
}
}
int size = list.size();
String [] arrayToSort = list.toArray(new String[size]);
Arrays.sort(arrayToSort);
StringBuilder sb = new StringBuilder();
for(int i = 0; i < size; i ++) {
sb.append(arrayToSort[i]);
}
String result = sb.toString();
//过滤最后一个字符串&
int lastIdx = result.lastIndexOf("&");
result = result.substring(0,lastIdx);
result += key;
try{
result = MD5.MD5Encode(result).toUpperCase();
}catch (Exception e) {
e.printStackTrace();
}
return result;
} /**
* 验签
* @param object
* @param key
* @return
* @throws Exception
*/
public static boolean checkIsSignValidFromResyponseStringObject(Object object,String key) throws Exception {
Map<String, String> map = objectToMap(object);
return checkIsSignValidFromResponseString(map,key);
} /**
* 验签
* @param map
* @param key
* @return
* @throws Exception
*/
public static boolean checkIsSignValidFromResponseString(Map<String,String> map,String key) throws Exception {
String signFromAPIResponse = null;
if(map.get("sign")!=null){
signFromAPIResponse = map.get("sign").toString();
}
if(signFromAPIResponse=="" || signFromAPIResponse == null){
return false;
} //清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
map.put("sign","");
map.put("class","");
//将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
//重新签名
String signForAPIResponse = Signature.getSign(map,key); if(!signForAPIResponse.equals(signFromAPIResponse)){
//签名验不过,表示这个API返回的数据有可能已经被篡改了
return false;
}
return true;
} //test
static class UserInfo{
private String userName;
private String idNo;
private String mobile;
private String sign; public String getSign() {
return sign;
} public void setSign(String sign) {
this.sign = sign;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getIdNo() {
return idNo;
} public void setIdNo(String idNo) {
this.idNo = idNo;
} public String getMobile() {
return mobile;
} public void setMobile(String mobile) {
this.mobile = mobile;
}
} /**
* 签名字符串:84CBF6035C54EAFE62E3F57F1737C733
* 参数json={"idNo":"463300122545556699","mobile":"19966667777","sign":"84CBF6035C54EAFE62E3F57F1737C733","userName":"张三"}
* 验证签名是否一致=true
* @param args
*/
public static void main(String[] args) {
try {
String key = "testkey111"; UserInfo userInfo = new UserInfo();
userInfo.setMobile("19966667777");
userInfo.setUserName("张三");
userInfo.setIdNo("463300122545556699");
String signStr = Signature.getSign(userInfo,key);
System.out.println("签名字符串:" + signStr);
userInfo.setSign(signStr);
System.out.println("参数json=" + JSON.toJSONString(userInfo)); //验证签名
boolean flag = Signature.checkIsSignValidFromResyponseStringObject(userInfo,key);
System.out.println("验证签名是否一致="+flag); } catch (Exception e) {
e.printStackTrace();
} }
}
import java.security.MessageDigest;

public class MD5 {
private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "a", "b", "c", "d", "e", "f"}; /**
* 转换字节数组为16进制字串
* @param b 字节数组
* @return 16进制字串
*/
public static String byteArrayToHexString(byte[] b) {
StringBuilder resultSb = new StringBuilder();
for (byte aB : b) {
resultSb.append(byteToHexString(aB));
}
return resultSb.toString();
} /**
* 转换byte到16进制
* @param b 要转换的byte
* @return 16进制格式
*/
private static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n = 256 + n;
}
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
} /**
* MD5编码
* @param origin 原始字符串
* @return 经过MD5加密之后的结果
*/
public static String MD5Encode(String origin) {
String resultString = null;
try {
resultString = origin;
MessageDigest md = MessageDigest.getInstance("MD5");
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
} catch (Exception e) {
e.printStackTrace();
}
return resultString;
}
}

Java接口签名和验签的更多相关文章

  1. java接口签名(Signature)实现方案续

    一.前言 由于之前写过的一片文章 (java接口签名(Signature)实现方案 )收获了很多好评,此次来说一下另一种简单粗暴的签名方案.相对于之前的签名方案,对body.paramenter.pa ...

  2. .NET RSA解密、签名、验签

    using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Sec ...

  3. gateway 网关接口防篡改验签

    gateway 网关接口防篡改验签 背景:为了尽可能降低接口在传输过程中,被抓包然后篡改接口内的参数的可能,我们可以考虑对接口的所有入参做签名验证,后端在网关依照相同的算法生成签名做匹配,不能匹配的返 ...

  4. PHP SHA1withRSA加密生成签名及验签

    最近公司对接XX第三方支付平台的代付业务,由于对方公司只有JAVA的demo,所以只能根据文档自己整合PHP的签名加密,网上找过几个方法,踩到各种各样的坑,还好最后算是搞定了,话不多说,代码分享出来. ...

  5. erlang的RSA签名与验签

    1.RSA介绍 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对 其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而 ...

  6. RSA后台签名前台验签的应用(前台采用jsrsasign库)

    写在前面 安全测试需要, 为防止后台响应数据返给前台过程中被篡改前台再拿被篡改后的数据进行接下来的操作影响正常业务, 决定采用RSA对响应数据进行签名和验签, 于是有了这篇<RSA后台签名前台验 ...

  7. 密码基础知识(2)以RSA为例说明加密、解密、签名、验签

    密码基础知识(1)https://www.cnblogs.com/xdyixia/p/11528572.html 一.RSA加密简介 RSA加密是一种非对称加密.是由一对密钥来进行加解密的过程,分别称 ...

  8. RSA/RSA2 进行签名和验签

    package com.byttersoft.hibernate.erp.szmy.util; import java.io.ByteArrayInputStream; import java.io. ...

  9. java接口签名(Signature)实现方案

    预祝大家国庆节快乐,赶快迎接美丽而快乐的假期吧!!! 一.前言 在为第三方系统提供接口的时候,肯定要考虑接口数据的安全问题,比如数据是否被篡改,数据是否已经过时,数据是否可以重复提交等问题.其中我认为 ...

  10. 中行P1签名及验签

    分享中国银行快捷.NET P1签名和验签方法代码中ReturnValue为自定义类型请无视 #region 验证签名 /// <summary> /// 验证签名 /// </sum ...

随机推荐

  1. 基于链路思想的SpringBoot单元测试快速写法

    ​简介:本文更偏向实践而非方法论,所提及的SpringBoot单元测试写法亦并非官方解,仅仅是笔者自身觉得比较方便.效率较高的一种写法.每个团队甚至团队内的每位开发可能都有自己的写法习惯和风格,只要能 ...

  2. [FAQ] FinalCutPro 竖版视频 加模糊背景变 横版视频

    把一段影片拖到时间轴上面,注意自定义尺寸选择 1920 x 1080,因为竖版的是 1080 x 1920. 切换到仅视频,并选择变形,视频区左右拖动视频到最大. 设置模糊效果为高斯曲线. 切回到全部 ...

  3. 修复 VisualStudio 构建时没有将 NuGet 的 PDB 符号文件拷贝到输出文件夹

    本文告诉大家如何修复 VisualStudio 构建时没有将 NuGet 的 PDB 符号文件拷贝到输出文件夹的问题.如果 VisualStudio 构建时没有将 NuGet 的 PDB 符号文件拷贝 ...

  4. k8s证书延长时间(二)

    1.查看证书有效时间 # 通过下面可看到ca证书有效期是10年,2022-2032 [root@master ~]# openssl x509 -in /etc/kubernetes/pki/ca.c ...

  5. 解锁HDC 2024之旅:从购票到报名,全程攻略

    本文分享自华为云社区<解锁HDC 2024之旅:从购票到报名,全程攻略>,作者:华为云社区精选. Hi,代码界的小伙伴们,集结号已经吹响了!华为开发者大会(HDC 2024)--这场汇聚了 ...

  6. 05. C语言数组

    数组用于将多个数据集中存储,方便管理,此文将任何集中存储一组数据的语句都称为数组,数组根据存储数据的类型和方式分为以下类型:数组.结构体.共用体.枚举. [数组] 数组用于存储多个类型相同的数据,可以 ...

  7. P3622 [APIO2007] 动物园 -题解

    好写 爱写 没事干 所以有了这篇题解 洛谷P3622 [APIO2007] 动物园 题解 $Link$ hzoi题库 洛谷 题目说的挺繁琐,其实就传达了一个很简单的信息: \(n\)个动物,\(c\) ...

  8. Linux环境下:程序的链接, 装载和库[可执行文件的装载]

    现代操作系统如何装载可执行文件? 给进程分配独立的虚拟地址空间 建立虚拟地址空间和可执行文件的映射关系 把CPU指令寄存器设置成可执行文件的入口地址,启动执行 可执行文件在装载的过程中实际上是映射的虚 ...

  9. Halcon无法连接Basler相机及图像不稳定的解决办法

    情况一:出现检测图片接口可以检测到GigE接口,但连接时显示不能初始化. 解决办法:这种首先确保相机网口连接稳定,并在Basler的自带驱动软件Pylon中将TriggerMode改为Off(Halc ...

  10. Swoole 源码分析之 WebSocket 模块

    首发原文链接:Swoole 源码分析之 WebSocket 模块 大家好,我是码农先森. Swoole 源码分析之 WebSocket 模块 引言 WebSocket 是一种在单个 TCP 连接上进行 ...