package com.byttersoft.hibernate.erp.szmy.util;

 import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map; import org.apache.commons.codec.binary.Base64; import com.byttersoft.framework.util.StringUtil;
/**
* RSA的签名及验签
* @author zhouyy
*
*/
public class RSA { private static final String SIGN_TYPE_RSA = "RSA"; private static final String SIGN_TYPE_RSA2 = "RSA2"; private static final String SIGN_ALGORITHMS = "SHA1WithRSA"; private static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA"; private static final int DEFAULT_BUFFER_SIZE = 8192; /**
* RSA/RSA2 生成签名
*
* @param map
* 包含 sign_type、privateKey、charset
* @return
* @throws Exception
*/
public static String rsaSign(Map map) throws Exception {
PrivateKey priKey = null;
java.security.Signature signature = null;
String signType = map.get("sign_type").toString();
String privateKey = map.get("privateKey").toString();
String charset = map.get("charset").toString();
String content = getSignContent(map);
map.put("content", content);
System.out.println("请求参数生成的字符串为:" + content);
if (SIGN_TYPE_RSA.equals(signType)) {
priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA, new ByteArrayInputStream(privateKey.getBytes()));
signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
} else if (SIGN_TYPE_RSA2.equals(signType)) {
priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA, new ByteArrayInputStream(privateKey.getBytes()));
signature = java.security.Signature.getInstance(SIGN_SHA256RSA_ALGORITHMS);
} else {
throw new Exception("不是支持的签名类型 : : signType=" + signType);
}
signature.initSign(priKey); if (StringUtil.isEmpty(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
} byte[] signed = signature.sign(); return new String(Base64.encodeBase64(signed)); } /**
* 验签方法
*
* @param content
* 参数的合成字符串格式: key1=value1&key2=value2&key3=value3...
* @param sign
* @param publicKey
* @param charset
* @param signType
* @return
*/
public static boolean rsaCheck(Map map, String sign) throws Exception {
java.security.Signature signature = null;
String signType = map.get("sign_type").toString();
String privateKey = map.get("privateKey").toString();
String charset = map.get("charset").toString();
String content = map.get("content").toString();
String publicKey = map.get("publicKey").toString();
System.out.println(">>验证的签名为:" + sign);
System.out.println(">>生成签名的参数为:" + content);
PublicKey pubKey = getPublicKeyFromX509("RSA", new ByteArrayInputStream(publicKey.getBytes()));
if (SIGN_TYPE_RSA.equals(signType)) {
signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
} else if (SIGN_TYPE_RSA2.equals(signType)) {
signature = java.security.Signature.getInstance(SIGN_SHA256RSA_ALGORITHMS);
} else {
throw new Exception("不是支持的签名类型 : signType=" + signType);
}
signature.initVerify(pubKey); if (StringUtil.isEmpty(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
} return signature.verify(Base64.decodeBase64(sign.getBytes()));
} public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, InputStream ins) throws Exception {
if (ins == null || StringUtil.isEmpty(algorithm)) {
return null;
} KeyFactory keyFactory = KeyFactory.getInstance(algorithm); byte[] encodedKey = readText(ins).getBytes(); encodedKey = Base64.decodeBase64(encodedKey); return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
} public static PublicKey getPublicKeyFromX509(String algorithm, InputStream ins) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm); StringWriter writer = new StringWriter();
io(new InputStreamReader(ins), writer, -1); byte[] encodedKey = writer.toString().getBytes(); encodedKey = Base64.decodeBase64(encodedKey); return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
} /**
* 把参数合成成字符串
*
* @param sortedParams
* @return
*/
public static String getSignContent(Map<String, String> sortedParams) {
StringBuffer content = new StringBuffer();
// app_id,method,charset,sign_type,version,bill_type,timestamp,bill_date
String[] sign_param = sortedParams.get("sign_param").split(",");// 生成签名所需的参数
List<String> keys = new ArrayList<String>();
for (int i = 0; i < sign_param.length; i++) {
keys.add(sign_param[i]);
}
Collections.sort(keys);
int index = 0;
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
/*if ("biz_content".equals(key)) {
content.append(
(index == 0 ? "" : "&") + key + "={\"bill_date\":\"" + sortedParams.get("bill_date") + "\",")
.append("\"bill_type\":\"" + sortedParams.get("bill_type") + "\"}");
index++;
} else {*/
String value = sortedParams.get(key);
if (StringUtil.isNotEmpty(key) && StringUtil.isNotEmpty(value)) {
content.append((index == 0 ? "" : "&") + key + "=" + value);
index++;
}
// }
}
return content.toString();
} private static String readText(InputStream ins) throws IOException {
Reader reader = new InputStreamReader(ins);
StringWriter writer = new StringWriter(); io(reader, writer, -1);
return writer.toString();
} private static void io(Reader in, Writer out, int bufferSize) throws IOException {
if (bufferSize == -1) {
bufferSize = DEFAULT_BUFFER_SIZE >> 1;
} char[] buffer = new char[bufferSize];
int amount; while ((amount = in.read(buffer)) >= 0) {
out.write(buffer, 0, amount);
}
} }

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. BZOJ 3589: 动态树 树链剖分+线段树+树链的并

    利用树剖序的一些性质~ 这个题可以出到 $\sum k=10^5$ 左右. 做法很简单:每次暴力跳重链,并在线段树上查询链和. 查询之后打一个标记,把加过的链都置为 $0$.这样的话在同一次询问时即使 ...

  2. POJ 1182食物链(并查集)

    食物链Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 85474 Accepted: 25549Description动物王国中有三 ...

  3. 51 Nod 一维战舰

    1521 一维战舰  题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 爱丽丝和鲍博喜欢玩一维战舰的游戏.他们在一行 ...

  4. JavaWeb_(SSH论坛)_七、辅助模块

    基于SSH框架的小型论坛项目 一.项目入门 传送门 二.框架整合 传送门 三.用户模块 传送门 四.页面显示 传送门 五.帖子模块 传送门 六.点赞模块 传送门 七.辅助模块 传送门 为避免代码冗余, ...

  5. LeetCode75----分类颜色(变相快排)

    给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 分别表示红色.白色和蓝色. ...

  6. 2019Java第十三周课程总结

    这周主要是学习了监听器还有制作记事本,主要可以由一下代码来体现 监听器 实验代码 package text12; import java.awt.Container; import java.awt. ...

  7. 【转】C++ const成员变量和成员函数(常成员函数)

    转:http://c.biancheng.net/view/2230.html 在类中,如果你不希望某些数据被修改,可以使用const关键字加以限定.const 可以用来修饰成员变量和成员函数. co ...

  8. 自定义view防支付成功页面

    package com.loaderman.customviewdemo; import android.content.Context; import android.graphics.Canvas ...

  9. redhat下配置SEED DVS6446开发环境2

    ---恢复内容开始--- 1.rpcbind步骤  linux包:portmap安装包 libgssglue-0.1-8.1.el6.i686.rpm libtirpc-0.2.1-1.el6.i68 ...

  10. 阶段3 2.Spring_09.JdbcTemplate的基本使用_2 JdbcTemplate的概述和入门

    先看这张图 1.spring中的JdbcTemplate     JdbcTemplate的作用:         它就是用于和数据库交互的,实现对表的CRUD操作     如何创建该对象:      ...