在日常的工作中,我们对外提供的接口或调用三方的接口往往有一步生成签名或验签的步骤,这个步骤主要是验证调用方是

不是合法的以及内容是否被修改。比如:对于某些网上公开下载的软件,视频,尤其是镜像文件。如果被修改了可能会导致用不了

或者其他的问题,发布者镜像MD5算法计算一组数值。让下载的用户进行MD5数值对比,也就是MD5校验啦。由于MD5加密不可逆算,

如果数值一样,那就表示文件没有被修改的。反之,则被修改了。

接下来通过文字介绍、代码、运行结果的方式给大家介绍RSA、MD5生成签名和验签;

一、MD5签名与验签

1.MD5介绍

MD5全名Message-Digest Algorithm 5(信息-摘要算法)是一种不可逆的加密算法。

MD5算法具有以下特点:

1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。

2、容易计算:从原数据计算出MD5值很容易。

3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

MD5生成签名和验签需要MD5 key,这个key值就是一段字符串没有任何限制比如:123456ADSEF

2.签名与验签流程

首先参数放入一个字符串数组signFields,把参数和值放入一个对象或map中,使用JSONObject把这个对象转化成json对象。

然后构建签名原文,在构建签名原文时,我们需把参数按照字典(比如a,b,c)顺序排序,具体排序方法直接调java的Arrays.sort方法。

然后按照key=value的方式把所有参数和值拼接成字符串,多个参数直接以“&”符号隔开,再然后把MD5 key拼接在该签名原文的最后。

最后使用MD5Encrypt.getMessageDigest(signSrc)生成签名。

验签很简单,验签方按照上面的签名流程生成的签名与传过来的签名作对比如果相等就验签成功,否则验签失败。

3.具体代码如下:

需验签的参数map:

Map<String ,Object> map=new HashMap<String,Object>();map.put("name", "小明");map.put("age", 12);map.put("sex", "男");map.put("school", "xxx中学");map.put("address", "xxx小区");

MD5生成签名字符串:

/*** MD5生成签名字符串* * @param map*            需签名参数* @param key*            MD5key* @return*/public static String MD5sign(Map<String, Object> map, String key) {String genSign = "";try {String[] signFields = new String[5];signFields[0] = "name";signFields[1] = "age";signFields[2] = "sex";signFields[3] = "school";signFields[4] = "address";JSONObject param = (JSONObject) JSONObject.toJSON(map);// 生成签名原文String signSrc = orgSignSrc(signFields, param);// MD5的方式签名signSrc += "&KEY=" + key;genSign = MD5Encrypt.getMessageDigest(signSrc);} catch (Exception e) {e.printStackTrace();}return genSign;}

构建签名原文:

/*** 构建签名原文* * @param signFilds 参数列表* @param param 参数与值的jsonbject* @return*/private static String orgSignSrc(String[] signFields, JSONObject param) {if (signFields != null) {Arrays.sort(signFields); // 对key按照 字典顺序排序}StringBuffer signSrc = new StringBuffer("");int i = 0;for (String field : signFields) {signSrc.append(field);signSrc.append("=");signSrc.append((StringUtil.isEmpty(param.getString(field)) ? "": param.getString(field)));// 最后一个元素后面不加&if (i < (signFields.length - 1)) {signSrc.append("&");}i++;}return signSrc.toString();}

MD5验证签名:

/*** MD5验证签名* @param map* @param key* @param sign* @return*/public static void vlidateMD5sign(Map<String ,Object> map,String key,String sign) {String vsign=MD5sign(map, key);System.out.println("MD5验证签名生成的签名:"+vsign);System.out.println("MD5验证签名生成的签名与原签名是否一致:sign=vsign true?false:"+(vsign.equals(sign)));}

main方法:

public static void main(String[] args) {Map<String ,Object> map=new HashMap<String,Object>();map.put("name", "小明");map.put("age", 12);map.put("sex", "男");map.put("school", "xxx中学");map.put("address", "xxx小区");/***MD5签名与验签**/String key="123456ADSEF";String sign= MD5sign(map,key);System.out.println("生成的MD5签名:"+sign);vlidateMD5sign(map, key, sign) ;}

执行结果:

生成的MD5签名:A82ED0D0E0155D3926E0A6B6B3EE60C4
MD5验证签名生成的签名:A82ED0D0E0155D3926E0A6B6B3EE60C4
MD5验证签名生成的签名与原签名是否一致:sign=vsign true?false:true

二、RSA签名与验签

1.RSA介绍

RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对

其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,

私钥则为自己所有,供解密之用。解密者拥有私钥,并且将由私钥计算生成的公钥发布给加密者。加密都使用公钥进行加密,并将密文发送

到解密者,解密者用私钥解密将密文解码为明文。

以甲要把信息发给乙为例,首先确定角色:甲为加密者,乙为解密者。首先由乙随机确定一个KEY,称之为密匙,将这个KEY始终保

存在机器B中而不发出来;然后,由这个 KEY计算出另一个KEY,称之为公匙。这个公钥的特性是几乎不可能通过它自身计算出生成它的私钥。

接下来通过网络把这个公钥传给甲,甲收到公钥后,利用公钥对信息加密,并把密文通过网络发送到乙,最后乙利用已知的私钥,就对密文进

行解码了。以上就是RSA算法的工作流程。

2.生成签名与验签流程

生成签名方:首先对参数放入一个字符串数组signFields,把参数和值放入一个对象或map中,使用JSONObject把这个对象转化成json对象。

然后构建签名原文,在构建签名原文时,我们需把参数按照字典(比如a,b,c)顺序排序,具体排序方法直接调java的Arrays.sort方法。 然后使用RSA

的私钥对签名原文进行签名。

验签方:和生产签名方一样先生成签名原文,然后使用RSA的公钥、生成签名方传入的签名及签名原文对生成签名方传入的签名进行验证,验

证结果为true说明验证成功,否则为未通过。

3.具体的代码实现

注:生成公钥和私钥可以使用RSA的相关工具也可以使用在线的web工具,网上工具很多的,一搜就出来了。我是用的是:http://web.chacuo.net/netrsakeypair这个在线工具。我采用的是密钥长度采用1024。

需验签的参数map:

Map<String ,Object> map=new HashMap<String,Object>();map.put("name", "小明");map.put("age", 12);map.put("sex", "男");map.put("school", "xxx中学");map.put("address", "xxx小区");

RSA公钥和私玥:

String prikey="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOq30rck7L3FshHVYWJK59sTToGMAn7WfYdrFN60AmPPyiMcIFXe3ZAxf7SWNbaQOPUz/xYr+oAXUBK17bykS/E2+Xa74wdN2VNbc7cZIggAjP9tGN0qhYTclbtC3pchcU8TVccrlVUN2lzJDLBHhPBDBFXzsQx9Vwtm2qjf2GcrAgMBAAECgYEAsHnz4aXOpkTNRSFVbiz5tLsIbNjTS4CDs1ysvWFE5rzls45DNa0yk2bUKPhDfHdli99DbO02FDbzCo5lKE+zlEHaC/WTp6guEe7jj5dwMl3shBZmgITCTk1/MQ46gGRG4RRADbQT/Y7tENp/GF3y9oJyJ+LmHFvfdEjSuY1/QzECQQD6aKqYFO8wuhLhy1fTvjMwlzok0szT9wTp+l6E7Ct9+csvdwaYjJrGsr6kUv+6YUwieSJ41lVtGnRy1oXEQG2TAkEA7/V35kYG+FMwYq/DOrBNaomRQGJVAOLzGRoK2dkjAkpoUAfzk4TTQ0KdJJ3T6mzF/6IQY+1oFDD42kNKJklfCQJARiya0i/bsC4VKI3RuRcuRUm8E6G3oRcym1d8sYd10MH1/QFAKfQNU+23m1lfLR4jNe34iSCXpBGr3JrdtdfQXQJAXgWRkGHZ800tRU3XMlTIULlMd6zP38QNOsWwgMGK7SfYjZs//opp+Q3N4v4QfedXAZ4vy+fHAzpZF7SMBkpzeQJALlMaKKeqKvPr8abXSRjW8u6s8tHaHX6CRV/1fGDX1bkUByqdFMO5CqIHn7isK2dHXI42bJVz63/d2Aax3lTbkA==";String pubkey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDqt9K3JOy9xbIR1WFiSufbE06BjAJ+1n2HaxTetAJjz8ojHCBV3t2QMX+0ljW2kDj1M/8WK/qAF1ASte28pEvxNvl2u+MHTdlTW3O3GSIIAIz/bRjdKoWE3JW7Qt6XIXFPE1XHK5VVDdpcyQywR4TwQwRV87EMfVcLZtqo39hnKwIDAQAB";

生成RSA签名字符串:

/*** RSA生成签名字符串* * @param map*            需签名参数* @param prikey*            rsa私钥* @return*/public static String RSAsign(Map<String, Object> map, String prikey) {String genSign = "";try {String[] signFields = new String[5];signFields[0] = "name";signFields[1] = "age";signFields[2] = "sex";signFields[3] = "school";signFields[4] = "address";JSONObject param = (JSONObject) JSONObject.toJSON(map);// 生成签名原文String src = orgSignSrc(signFields, param);genSign = RsaUtil.sign(src, prikey);} catch (Exception e) {e.printStackTrace();}return genSign;}

构建签名原文:

/*** 构建签名原文* * @param signFilds 参数列表* @param param 参数与值的jsonbject* @return*/private static String orgSignSrc(String[] signFields, JSONObject param) {if (signFields != null) {Arrays.sort(signFields); // 对key按照 字典顺序排序}StringBuffer signSrc = new StringBuffer("");int i = 0;for (String field : signFields) {signSrc.append(field);signSrc.append("=");signSrc.append((StringUtil.isEmpty(param.getString(field)) ? "": param.getString(field)));// 最后一个元素后面不加&if (i < (signFields.length - 1)) {signSrc.append("&");}i++;}return signSrc.toString();}

RSA验证签名:

/*** RSA验证签名* @param map 参与验签的参数* @param sign 签名者传入的签名* @param publickey 公钥* @return*/public static String vlidateRSAsign(Map<String, Object> map, String sign,String publickey) {String genSign = "";try {String[] signFields = new String[5];signFields[0] = "name";signFields[1] = "age";signFields[2] = "sex";signFields[3] = "school";signFields[4] = "address";JSONObject param = (JSONObject) JSONObject.toJSON(map);// 生成签名原文String signSrc = orgSignSrc(signFields, param);// 调用工具类验签boolean bool = RsaUtil.verify(signSrc, sign, publickey);System.out.println("验证签名生成的签名与原签名是否一致: true?false:" + bool);} catch (Exception e) {e.printStackTrace();}return genSign;}

main方法:

public static void main(String[] args) {Map<String ,Object> map=new HashMap<String,Object>();map.put("name", "小明");map.put("age", 12);map.put("sex", "男");map.put("school", "xxx中学");map.put("address", "xxx小区");/***RSA签名与验签**/String prikey="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOq30rck7L3FshHVYWJK59sTToGMAn7WfYdrFN60AmPPyiMcIFXe3ZAxf7SWNbaQOPUz/xYr+oAXUBK17bykS/E2+Xa74wdN2VNbc7cZIggAjP9tGN0qhYTclbtC3pchcU8TVccrlVUN2lzJDLBHhPBDBFXzsQx9Vwtm2qjf2GcrAgMBAAECgYEAsHnz4aXOpkTNRSFVbiz5tLsIbNjTS4CDs1ysvWFE5rzls45DNa0yk2bUKPhDfHdli99DbO02FDbzCo5lKE+zlEHaC/WTp6guEe7jj5dwMl3shBZmgITCTk1/MQ46gGRG4RRADbQT/Y7tENp/GF3y9oJyJ+LmHFvfdEjSuY1/QzECQQD6aKqYFO8wuhLhy1fTvjMwlzok0szT9wTp+l6E7Ct9+csvdwaYjJrGsr6kUv+6YUwieSJ41lVtGnRy1oXEQG2TAkEA7/V35kYG+FMwYq/DOrBNaomRQGJVAOLzGRoK2dkjAkpoUAfzk4TTQ0KdJJ3T6mzF/6IQY+1oFDD42kNKJklfCQJARiya0i/bsC4VKI3RuRcuRUm8E6G3oRcym1d8sYd10MH1/QFAKfQNU+23m1lfLR4jNe34iSCXpBGr3JrdtdfQXQJAXgWRkGHZ800tRU3XMlTIULlMd6zP38QNOsWwgMGK7SfYjZs//opp+Q3N4v4QfedXAZ4vy+fHAzpZF7SMBkpzeQJALlMaKKeqKvPr8abXSRjW8u6s8tHaHX6CRV/1fGDX1bkUByqdFMO5CqIHn7isK2dHXI42bJVz63/d2Aax3lTbkA==";String pubkey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDqt9K3JOy9xbIR1WFiSufbE06BjAJ+1n2HaxTetAJjz8ojHCBV3t2QMX+0ljW2kDj1M/8WK/qAF1ASte28pEvxNvl2u+MHTdlTW3O3GSIIAIz/bRjdKoWE3JW7Qt6XIXFPE1XHK5VVDdpcyQywR4TwQwRV87EMfVcLZtqo39hnKwIDAQAB";String rsaSign= RSAsign(map,prikey);System.out.println("生成的RSA签名:"+rsaSign);vlidateRSAsign(map, rsaSign, pubkey) ;}

执行结果:

生成的RSA签名:6AFF1E6A6CE17516D56ED94999E24FC6169290E111E207C4D9EFA57DA04525D173032FE32B620D16335164226420D0EDEE5EE5F9C9B413DAF2B7F418AE4EA17E055D718B1C1CB188A9BBBE1C5CF559C0BD5CADF83468D62C29635EF7CDE6B6AF0D63137A8FDA3CB26996DFBA3C505EDC04A843224AD1BBCA34ACD80EF7C3C5CA
验证签名生成的签名与原签名是否一致: true?false:true

以上就是MD5、RSA签名与验签的介绍。

注:关于本文使用的MD5Encrypt、RsaUtil类文件及相关的jar包,由于代码比较多,在这里就不贴出来了。我直接把demo源码上传到我的空间,大家可以免费下载。地址如下:

http://download.csdn.net/detail/mr_smile2014/9596252

使用RSA、MD5对参数生成签名与验签相关推荐

  1. asp版 vbscript RSA公钥加密 / 私钥解密 / 私钥签名 / 公钥验签(支持中文)分段加密解密

    最近有空在把自己的asp站点后端函数全部整理了下,在弄RSA的时候遇到了坑了,然后找到下面这位兄弟刚好发布的文章: https://blog.csdn.net/todaygods/article/de ...

  2. ASP VBSCRIPT VBA RSA 公钥加密 私钥解密 私钥签名 公钥验签

    <% '@title: Class_Crypt_Rsa '@author: ekede.com '@date: 2020-10-28 '@description: RSA 公钥加密->私钥 ...

  3. .NET WebApi实现RSA加密与解密,签名与验签

    WebApi接口签名加密和验签 业务场景需求 生成RSA密钥对 报文根据规则进行排序 用请求方的私钥对报文签名 用接收方的公钥对报文加密 发送密文给接收方,用接收方的密钥解密 接收方对数据验签 关于C ...

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

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

  5. RSA加密、解密、签名、验签(验证签名)RSA算法原理

    转载链接:https://www.jianshu.com/p/8dc4a5f64e06 https://www.cnblogs.com/pcheng/p/9629621.html RSA原理:http ...

  6. MD5数字签名算法:生成签名和验签(附代码)

    一.背景 为了增加接口的安全性(防止中间人攻击),现增加签名算法.此算法参考微信支付中的签名算法,由于该签名针对前后端,采用了对称算法,如后续接口供给多家第三方接口使用可采用非对称算法.大致整理文档供 ...

  7. 微信支付生成签名和验签SDK源码分析

    目录 一.签名分析 1.1 流程分析 1.构造签名串 2.计算签名值 3.设置请求头 二.源码级别分析 二.获取平台证书分析 三.验签分析 3.1 验签使用场景: 3.2 验证流程: 1.获取微信平台 ...

  8. RSA加密、解密、签名、验签的原理及方法

    目录 一.RSA加密简介 二.公钥与私钥的理解 三.RSA加密解密 四.RSA签名和验证 五.加密的作用 六.两种不同的加密与解密 七.RSA加密.签名区别 八.RSA加密.签名的方法,代码例子如下: ...

  9. RSA加密、解密、签名、验签介绍

    参考链接:https://www.cnblogs.com/pcheng/p/9629621.html RAS简介 RSA加密是非对称加密,由一对秘钥进行完成加密解密,分别称为公钥和私钥,公钥加密,私钥 ...

最新文章

  1. 【分布式架构】“高并发” -- 详解
  2. bat maven 一键打包 2.0
  3. [转]计算机学习道路
  4. ASP.NET 文件上传于下载
  5. 多线程:三大不安全案例
  6. 字节二面:优化 HTTPS 的手段,你知道几个?
  7. 基于C语言及51单片机的PID控制电机调速详解(附详细代码及Protsus仿真)
  8. hc05模块android代码,Arduino使用HC05蓝牙模块与手机连接
  9. attention权重解读
  10. [电影]《指环王》新老三部曲完全赏析(王者归来)
  11. docker 之容器编排工具Docker Compose
  12. 如何通便清肠快速见效_如何排毒清肠通便
  13. 【蓝桥杯】2019年第十届蓝桥杯(个人赛) 大赛介绍、注意事项及赛后总结
  14. android 微信高仿,Android高仿微信聊天界面代码分享
  15. this关键字及 this关键字的应用
  16. SaaS、PaaS、DaaS、IaaS四种云系统说明
  17. 简单谈谈如何提高后台管理系统的易用性、可操作性和人性化程度
  18. OA厂商的硬实力—技术水平
  19. 网络安全与渗透:信息收集——google浏览器插件,代理服务(五)此生无悔入华夏,男儿何不带吴钩
  20. amd同步多线程_流言终结者系列:第三代锐龙关同步多线程能增加游戏帧数?

热门文章

  1. 扫描二维码实现后台管理系统登录
  2. java thread dump
  3. UML建模学成在线管理系统
  4. 微信小程序的登录界面实现
  5. tcpreplay命令详解
  6. 过滤器和拦截器(SpringMVC实现)
  7. 工控机与arm主板有什么不同
  8. python图像识别依赖包安装和环境配置
  9. 2020.10.3--PS--模糊工具、减淡工具、橡皮擦工具
  10. Android Studio App开发之循环试图RecyclerView,布局管理器LayoutManager、动态更新循环视图讲解及实战(附源码)