RSA加签解签方法

article/2025/10/7 12:00:05

一、RSA签名的过程

(1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。

(2)A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B。

(3)B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的。

  在这个过程中,只有2次传递过程,第一次是A传递加签的消息和消息本身给B,第二次是B获取A的公钥,即使都被敌方截获,也没有危险性,因为只有A的私钥才能对消息进行签名,即使知道了消息内容,也无法伪造带签名的回复给B,防止了消息内容的篡改。

二、具体使用方法

1.通过RSA秘钥生成工具生成一对公钥和私钥

 

2.定义加密解密和加签验签方法名

//加密解密算法
private static final String ALGORITHM_RSA = "RSA";
​
//加签验签算法
private static final String ALGORITHM_SHA1WITHRSA = "SHA1withRSA";
​
private static final String CHARSET = "UTF-8";

 

3.加密解密方法

(1)初始化公钥私钥

/*** 初始化公钥私钥,将公钥私钥放入map中* @return* @throws NoSuchAlgorithmException*/
public static Map<String, Object> initKey() throws NoSuchAlgorithmException {//获得对象 KeyPairGenerator 参数 RSA 1024个字节KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM_RSA);keyPairGenerator.initialize(1024);KeyPair keyPair = keyPairGenerator.generateKeyPair();RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();//将公私钥对象存入map中,PUBLIC_KEY和PRIVATE_KEY为你自动生成的公私钥Map<String, Object> keyMap = new HashMap<>(2);keyMap.put(PUBLIC_KEY,rsaPublicKey);keyMap.put(PRIVATE_KEY,rsaPrivateKey);return keyMap;
}

(2)获取规范公钥和规范私钥

public static String getPublicKey(Map<String, Object> keyMap) throws Exception {Key key = (Key) keyMap.get(PUBLIC_KEY);return Base64.encodeBase64String(key.getEncoded());
}
​
/*** 将原始私钥进行处理,获取规范私钥* @param keyMap* @return 返回规范私钥* @throws Exception*/
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {Key key = (Key) keyMap.get(PRIVATE_KEY);
​return Base64.encodeBase64String(key.getEncoded());
}

(3)键值对转换成url方法

加签过程中需要通过formatSignContent()函数进行格斯转换,将键值对格式转换为url参数格式

/*** 格式转换,将map中键值对转换为url参数格式* @param params 传递参数的键值对,用map保存* @return 参数的url表示方法,例如:key1=111&key2=222*/
private static String formatSignContent(Map<String, String> params) {//利用TreeMap将键值对排序Map<String, String> sortedParams = new TreeMap<String, String>();sortedParams.putAll(params);StringBuilder content = new StringBuilder();int index = 0;for (Object key : sortedParams.keySet()){Object value = sortedParams.get(key.toString());if (value != null && StringUtils.isNotBlank(value.toString())) {content.append(index == 0 ? "" : "&").append(key).append("=").append(value);index++;}}return content.toString();
}

(4)加签方法

A通过自己的私钥对原始数据进行加签,生成加签数据sign,期间需要格式转换

/*** RSA加签方法* @param paramsMap 原始数据键值对格式* @param privateKey 私钥* @return 返回加签数据* @throws Exception*/
private static String signWithRSA(Map<String,String> paramsMap, String privateKey) throws Exception {//将Map键值对转换为url参数格式String content = formatSignContent(paramsMap);//指定加签算法Signature signature = Signature.getInstance(ALGORITHM_SHA1WITHRSA);signature.initSign(getPrivateKey(privateKey));signature.update(content.getBytes("utf-8"));byte[] signed = signature.sign();return Base64.encodeBase64String(signed);
}

(5)验签方法

B通过A的公钥和加签数据sign以及传递的参数map进行解签

/*** RSA验签方法* 将传递的Map键值对转换为url参数形式* @param paramsMap 传递过来的键值对* @param publicKey 规范公钥* @param sign 加签后的数据* @return 验签结果* @throws Exception*/
private static boolean checkSignWithRSA(Map<String,String> paramsMap, String publicKey, String sign) throws Exception {String content = formatSignContent(paramsMap);Signature signature = Signature.getInstance("SHA1WithRSA");signature.initVerify(getPublicKey(publicKey));signature.update(content.getBytes("utf-8"));return signature.verify(Base64.decodeBase64(sign));
}

(6)实际使用示例

/**验证加签验签流程* 1.A通过自己的私钥对原数据map进行加签,加签后的数据sign* 2.A将加签数据sign和原始数据map发送给另外一方B* 3.B通过加签数据sign和传递过来的数据map进行通过A的公钥进行解签* RSA加签验签方法* @return 是否正确* @throws Exception*/
public static boolean verifySingCheck() throws Exception {Map<String, Object> keyMap = initKey();//得到原始公钥、私钥存储的mapString publicKey = getPublicKey(keyMap);//获取规范公钥String privateKey = getPrivateKey(keyMap);//获取规范私钥
​Map<String,String> map = new HashMap<>();map.put("key1","111");map.put("key2","222");
​//传递过程发生了改变Map<String,String> map2 = new HashMap<>();map2.put("key1","111222");map2.put("key2","222");
​String sign = signWithRSA(map,privateKey);boolean check = checkSignWithRSA(map,publicKey,sign);//boolean check = checkSignWithRSA(map2,publicKey,sign);//传递过程发生了改变System.out.println("签名结果,sign:"+sign);System.out.println("验签结果,result:"+check);return check;
}


http://chatgpt.dhexx.cn/article/Cgdhrk9M.shtml

相关文章

安全对外的接口--加签验签

前言 我们在求职面试中,经常会被问到,如何设计一个安全对外的接口呢? 其实可以回答这一点,加签和验签,这将让你的接口更加有安全。接下来,本文将和大家一起来学习加签和验签。从理论到实战,加油哦~ 密码学相关概念加签验签概念为什么需要加签、验签加密算法简介加签验签…

程序员必备基础:加签验签

来源&#xff1a;捡田螺的小男孩 我们在求职面试中&#xff0c;经常会被问到&#xff0c;如何设计一个安全对外的接口呢? 其实可以回答这一点&#xff0c;加签和验签&#xff0c;这将让你的接口更加有安全。接下来&#xff0c;本文将和大家一起来学习加签和验签。从理论到实战…

RSA公私钥加密加签顺序

RSA是一种非对称加密的机制&#xff0c;是一对密钥对&#xff08;公钥和私钥&#xff09;。 一、加密&#xff1a; 1.公钥加密&#xff0c;私钥解密。可以多人持有公钥进行数据加密&#xff0c;仅一人持有私钥进行数据解密&#xff1b; 2.可以确保数据传输的安全性。 二、加签…

【flowable】十一、flowable加签和转签

flowable加签和转签 加签 同时让多人处理任务&#xff0c;但是不同于网关操作。 1、向前加签 任务在A这里&#xff0c;A这个时候需要BCD核对一下&#xff0c;等BCD核对之后又回到A这里 2、向后加签 任务在A这里&#xff0c;A这个时候需要BCD处理这个事情&#xff0c;处理完毕…

加解密,加签、验签也就这肥事

前言&#xff1a; ps:上图有一处错误&#xff0c;右下角有一条线是N&#xff0c;指向的是不读取内容 上图省略了CA认证过程&#xff0c;直接提取到了密钥对&#xff0c;Base64的过程已省略(关于Base64的底层原理&#xff0c;可参考标题3)。全文1.6w字&#xff0c;如果想全部…

前后端分离技术之加签,验签,防篡改

上一篇讲解了加密解密&#xff0c;这次来个加签验签&#xff0c;实际项目里&#xff0c;我们采用的是react 和nodejs 来进行加签验签&#xff0c;用的jsrsasign库&#xff0c;下面贴点核心代码 react加签 nodejs验签 实际应用在nodejs层可以将时间戳和sign签名验证通过剔除掉&…

深入探究Camunda加签问题

开源项目介绍&#xff1a;点击直达 前言 这里我们先抛出两个大问题&#xff0c;整篇文章针对这两个大问题再详细解析。 首先我们在设计流程定义时&#xff0c;流程节点可能是或签也可能是会签 会签&#xff1a;指同一个审批节点设置多个人&#xff0c;如ABC三人&#xff0c…

activity多实例任务加签

前言 加签是减签的相反的操作,加签与减签的思路刚好相反,减签是删数据;加签则是添加数据。在一些特殊场景下,需要在某个多实例节点上面动态新增一个审批人员或任务时,就需使用到activity多实例任务加签的功能 加签思路1 根据一级流程实例查找二级流程执行实例判断二级执…

Activiti7工作流引擎:进阶篇(十二) 加签和转签

知识传送门 》》》》》》》》》》》》》》》》》》》 加签就是委派任务delegateTask&#xff0c;然后去解决任务resolveTask&#xff08;并不是去真正的去完成任务&#xff09;。转签完成后才能完成任务complete。 一&#xff1a;委派任务 A由于某些原因不能处理该任务可以把任…

必备基础:加签验签

必备基础&#xff1a;加签验签 1 密码学相关概念1.1 明文、密文、密钥、加密、解密1.2 对称加密、非对称加密1.3 什么是公钥私钥&#xff1f; 2 加签验签概念3 为什么需要加签验签4 常见加密相关算法简介4.1 消息摘要算法4.1.1 MD家族算法4.1.2 ShA家族算法4.1.3 MAC算法家族 4…

Flowable工作流之加签(委派)、转签(转办)

目录 1. 加签1.1. 向前加签1.2. 向后加签 2. 或签3. 委派和转办的区别2.1. 委派2.2. 转办 4. 向前加签4.1. 流程图4.2. 部署并启动4.3. 完成任务4.4. 向前加签实现4.4.1. 添加加签&#xff08;委派&#xff09;功能任务4.4.1. 加签&#xff08;委派&#xff09;任务的完成 5. 转…

加密、解密、加签、验签专题

首先明确几个名词&#xff1a; 加密&#xff1a;发送方利用接收方的公钥对要发送的明文进行加密。 解密&#xff1a;接受方利用自己的私钥进行解密。 公钥和私钥配对的&#xff0c;用公钥加密的文件&#xff0c;只有对应的私钥才能解密。当然也可以反过来&#xff0c;用私钥…

@ControllerAdvice 之 @InitBinder和@ModelAttribute

InitBinder 准备 InitBinder 在整个 HandlerAdapter 调用过程中所处的位置 收获&#x1f4a1; RequestMappingHandlerAdapter 初始化时会解析 ControllerAdvice 中的 InitBinder 方法&#xff08;可以定义个性化数据转化器&#xff09;RequestMappingHandlerAdapter 会以类…

SpringBoot @InitBinder注解实现Bean国际化校验

参考资料 参考&#xff1a; 妥当性チェックのエラーメッセージ出力方法 (需翻墙)springMVC之InitBinder的用法1springMVC之InitBinder的用法2springMVC之InitBinder 和 ValidatorSpring MVCにおけるフォームバリデーションの適用事例【後編】 目录 一. 前期准备1.1 自定义校验…

SpringMVC之@InitBinder注解(日期转换)

InitBinder注解的作用&#xff1a; springmvc并不是能对所有类型的参数进行绑定的&#xff0c;如果对日期Date类型参数进行绑定&#xff0c;就会报错IllegalStateException错误。所以需要注册一些类型绑定器用于对参数进行绑定。InitBinder注解就有这个作用。 程序代码示例&am…

initbinder对ajax不起作用,Spring MVC InitBinder验证方法

使用InitBinder做验证的情况一般会在此Controller中提交的数据需要有一些是业务性质的&#xff0c;也即比较复杂的验证情况下才会使用。大部份简单的表单验证&#xff0c;使用annotation验证即可以解决。 这里需要注意的一点&#xff1a;InitBinder和Annotation两种验证只能二选…

SpringMvc @InitBinder

这篇博客记录InitBinder怎么起作用、起什么作用&#xff1f; 首先,该注解被解析的时机&#xff0c;是该匹配Controller的请求执行映射的方法之前; 同时 InitBinder标注的方法执行是多次的&#xff0c;一次请求来就执行一次。 当某个Controller上的第一次请求由SpringMvc前端控制…

java培训之InitBinder注解

InitBinder注解【了解】 InitBinder由 InitBinder 标识的方法&#xff0c;可以对 WebDataBinder 对象进行初始化。WebDataBinder 是 DataBinder 的子类&#xff0c;用于完成由表单字段到 JavaBean 属性的绑定InitBinder方法不能有返回值&#xff0c;它必须声明为void。InitBin…

SpringBoot @InitBinder注解绑定请求参数

参考资料 springMVC之InitBinder 和 ValidatorspringMVC之InitBinder的用法1springMVC之InitBinder的用法2 目录 一. 作用二. 前期准备三. Get请求 URL传值处理3.1 前台-test16.html3.2 Controller层3.3 效果 四. Post请求 表单传值 自定义日期属性绑定器4.1 前台-test16.h…

详细分析@InitBinder注解的使用和原理

前言 由InitBinder注解修饰的方法用于初始化WebDataBinder对象&#xff0c;能够实现&#xff1a;从request获取到handler方法中由RequestParam注解或PathVariable注解修饰的参数后&#xff0c;假如获取到的参数类型与handler方法上的参数类型不匹配&#xff0c;此时可以使用初…