1. package com.byttersoft.hibernate.erp.szmy.util;
  2.  
  3. import java.io.ByteArrayInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.InputStreamReader;
  7. import java.io.Reader;
  8. import java.io.StringWriter;
  9. import java.io.Writer;
  10. import java.security.KeyFactory;
  11. import java.security.PrivateKey;
  12. import java.security.PublicKey;
  13. import java.security.spec.PKCS8EncodedKeySpec;
  14. import java.security.spec.X509EncodedKeySpec;
  15. import java.util.ArrayList;
  16. import java.util.Collections;
  17. import java.util.List;
  18. import java.util.Map;
  19.  
  20. import org.apache.commons.codec.binary.Base64;
  21.  
  22. import com.byttersoft.framework.util.StringUtil;
  23. /**
  24. * RSA的签名及验签
  25. * @author zhouyy
  26. *
  27. */
  28. public class RSA {
  29.  
  30. private static final String SIGN_TYPE_RSA = "RSA";
  31.  
  32. private static final String SIGN_TYPE_RSA2 = "RSA2";
  33.  
  34. private static final String SIGN_ALGORITHMS = "SHA1WithRSA";
  35.  
  36. private static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
  37.  
  38. private static final int DEFAULT_BUFFER_SIZE = 8192;
  39.  
  40. /**
  41. * RSA/RSA2 生成签名
  42. *
  43. * @param map
  44. * 包含 sign_type、privateKey、charset
  45. * @return
  46. * @throws Exception
  47. */
  48. public static String rsaSign(Map map) throws Exception {
  49. PrivateKey priKey = null;
  50. java.security.Signature signature = null;
  51. String signType = map.get("sign_type").toString();
  52. String privateKey = map.get("privateKey").toString();
  53. String charset = map.get("charset").toString();
  54. String content = getSignContent(map);
  55. map.put("content", content);
  56. System.out.println("请求参数生成的字符串为:" + content);
  57. if (SIGN_TYPE_RSA.equals(signType)) {
  58. priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA, new ByteArrayInputStream(privateKey.getBytes()));
  59. signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  60. } else if (SIGN_TYPE_RSA2.equals(signType)) {
  61. priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA, new ByteArrayInputStream(privateKey.getBytes()));
  62. signature = java.security.Signature.getInstance(SIGN_SHA256RSA_ALGORITHMS);
  63. } else {
  64. throw new Exception("不是支持的签名类型 : : signType=" + signType);
  65. }
  66. signature.initSign(priKey);
  67.  
  68. if (StringUtil.isEmpty(charset)) {
  69. signature.update(content.getBytes());
  70. } else {
  71. signature.update(content.getBytes(charset));
  72. }
  73.  
  74. byte[] signed = signature.sign();
  75.  
  76. return new String(Base64.encodeBase64(signed));
  77.  
  78. }
  79.  
  80. /**
  81. * 验签方法
  82. *
  83. * @param content
  84. * 参数的合成字符串格式: key1=value1&key2=value2&key3=value3...
  85. * @param sign
  86. * @param publicKey
  87. * @param charset
  88. * @param signType
  89. * @return
  90. */
  91. public static boolean rsaCheck(Map map, String sign) throws Exception {
  92. java.security.Signature signature = null;
  93. String signType = map.get("sign_type").toString();
  94. String privateKey = map.get("privateKey").toString();
  95. String charset = map.get("charset").toString();
  96. String content = map.get("content").toString();
  97. String publicKey = map.get("publicKey").toString();
  98. System.out.println(">>验证的签名为:" + sign);
  99. System.out.println(">>生成签名的参数为:" + content);
  100. PublicKey pubKey = getPublicKeyFromX509("RSA", new ByteArrayInputStream(publicKey.getBytes()));
  101. if (SIGN_TYPE_RSA.equals(signType)) {
  102. signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  103. } else if (SIGN_TYPE_RSA2.equals(signType)) {
  104. signature = java.security.Signature.getInstance(SIGN_SHA256RSA_ALGORITHMS);
  105. } else {
  106. throw new Exception("不是支持的签名类型 : signType=" + signType);
  107. }
  108. signature.initVerify(pubKey);
  109.  
  110. if (StringUtil.isEmpty(charset)) {
  111. signature.update(content.getBytes());
  112. } else {
  113. signature.update(content.getBytes(charset));
  114. }
  115.  
  116. return signature.verify(Base64.decodeBase64(sign.getBytes()));
  117. }
  118.  
  119. public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, InputStream ins) throws Exception {
  120. if (ins == null || StringUtil.isEmpty(algorithm)) {
  121. return null;
  122. }
  123.  
  124. KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
  125.  
  126. byte[] encodedKey = readText(ins).getBytes();
  127.  
  128. encodedKey = Base64.decodeBase64(encodedKey);
  129.  
  130. return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
  131. }
  132.  
  133. public static PublicKey getPublicKeyFromX509(String algorithm, InputStream ins) throws Exception {
  134. KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
  135.  
  136. StringWriter writer = new StringWriter();
  137. io(new InputStreamReader(ins), writer, -1);
  138.  
  139. byte[] encodedKey = writer.toString().getBytes();
  140.  
  141. encodedKey = Base64.decodeBase64(encodedKey);
  142.  
  143. return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
  144. }
  145.  
  146. /**
  147. * 把参数合成成字符串
  148. *
  149. * @param sortedParams
  150. * @return
  151. */
  152. public static String getSignContent(Map<String, String> sortedParams) {
  153. StringBuffer content = new StringBuffer();
  154. // app_id,method,charset,sign_type,version,bill_type,timestamp,bill_date
  155. String[] sign_param = sortedParams.get("sign_param").split(",");// 生成签名所需的参数
  156. List<String> keys = new ArrayList<String>();
  157. for (int i = 0; i < sign_param.length; i++) {
  158. keys.add(sign_param[i]);
  159. }
  160. Collections.sort(keys);
  161. int index = 0;
  162. for (int i = 0; i < keys.size(); i++) {
  163. String key = keys.get(i);
  164. /*if ("biz_content".equals(key)) {
  165. content.append(
  166. (index == 0 ? "" : "&") + key + "={\"bill_date\":\"" + sortedParams.get("bill_date") + "\",")
  167. .append("\"bill_type\":\"" + sortedParams.get("bill_type") + "\"}");
  168. index++;
  169. } else {*/
  170. String value = sortedParams.get(key);
  171. if (StringUtil.isNotEmpty(key) && StringUtil.isNotEmpty(value)) {
  172. content.append((index == 0 ? "" : "&") + key + "=" + value);
  173. index++;
  174. }
  175. // }
  176. }
  177. return content.toString();
  178. }
  179.  
  180. private static String readText(InputStream ins) throws IOException {
  181. Reader reader = new InputStreamReader(ins);
  182. StringWriter writer = new StringWriter();
  183.  
  184. io(reader, writer, -1);
  185. return writer.toString();
  186. }
  187.  
  188. private static void io(Reader in, Writer out, int bufferSize) throws IOException {
  189. if (bufferSize == -1) {
  190. bufferSize = DEFAULT_BUFFER_SIZE >> 1;
  191. }
  192.  
  193. char[] buffer = new char[bufferSize];
  194. int amount;
  195.  
  196. while ((amount = in.read(buffer)) >= 0) {
  197. out.write(buffer, 0, amount);
  198. }
  199. }
  200.  
  201. }

RSA/RSA2 进行签名和验签的更多相关文章

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

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

  2. Delphi支付宝支付【支持SHA1WithRSA(RSA)和SHA256WithRSA(RSA2)签名与验签】

    作者QQ:(648437169) 点击下载➨Delphi支付宝支付             支付宝支付api文档 [Delphi支付宝支付]支持条码支付.扫码支付.交易查询.交易退款.退款查询.交易撤 ...

  3. Delphi RSA签名与验签【支持SHA1WithRSA(RSA1)、SHA256WithRSA(RSA2)和MD5WithRSA签名与验签】

    作者QQ:(648437169) 点击下载➨ RSA签名与验签 [delphi RSA签名与验签]支持3种方式签名与验签(SHA1WithRSA(RSA1).SHA256WithRSA(RSA2)和M ...

  4. erlang的RSA签名与验签

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

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

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

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

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

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

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

  8. 中行P1签名及验签

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

  9. 几个例子理解对称加密与非对称加密、公钥与私钥、签名与验签、数字证书、HTTPS加密方式

    # 原创,转载请留言联系 为什么会出现这么多加密啊,公钥私钥啊,签名啊这些东西呢?说到底还是保证双方通信的安全性与完整性.例如小明发一封表白邮件给小红,他总不希望给别人看见吧.而各种各样的技术就是为了 ...

随机推荐

  1. 树莓派设定笔记(Raspberry Pi 3 B+)

    树莓派默认用户名密码 pi / raspberry 一.启用root用户 设置root用户密码 sudo passwd root 开启root账户 sudo passwd --unlock root ...

  2. three months timestamp

    1.有效期三个月 package com.hengqin.life.idps; import java.text.SimpleDateFormat; import java.util.Calendar ...

  3. jquery focus()方法 语法

    jquery focus()方法 语法 作用:当元素获得焦点时,发生 focus 事件.大理石平台价格 触发focus事件语法:$(selector).focus() 将函数绑定到focus事件语法: ...

  4. 用JavaScript实现div的鼠标拖拽效果

    实现原理鼠标按下时根据onmousemove事件来动态获取鼠标坐标位置以此来更新div的位置,实现的前提时div要有一个定位效果,不然的话是移动不了它的. HTML <div class=&qu ...

  5. 分布式-信息方式-ActiveMQ的静态网络连接

                           ActiveMQ的静态网络连接 在一台服务器上启动多个Broker步骤如下:1:把整个conf文件夹复制一份,比如叫做conf22:修改里面的 activ ...

  6. 用了 EventBus 不要多用其他的通讯功能

    EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间.组件与后台线程间的通信.主要功能是替代Intent,Handler,BroadCast

  7. 02.替换空格 (Java)

    题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 思路 感觉这题对于Java意义 ...

  8. 第六周学习总结&java实验报告四

    第六周学习总结&java实验报告四 学习总结: 上一周因为接近国庆假期,所以老师没有讲太多的新知识点,只要是带我们一起做了一个动物模拟变声器的实验,进一步了解和学习到继承的 有关知识点和应用: ...

  9. spark streaming 3: Receiver 到 submitJobSet

     对于spark streaming来说,receiver是数据的源头.spark streaming的框架上,将receiver替换spark-core的以磁盘为数据源的做法,但是数据源(如监听某个 ...

  10. 使用EXSI创建虚拟机

    使用exsi创建虚拟主机之前需要确定好使用什么系统来创建虚拟主机,而本地电脑上的镜像服务器是无法直接使用的,我们需要先将镜像上传到服务器的存储器上,然后才能在提供给虚拟服务器使用,如何替换呢,参考下方 ...