RSA/RSA2 进行签名和验签
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 进行签名和验签的更多相关文章
- .NET RSA解密、签名、验签
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Sec ...
- Delphi支付宝支付【支持SHA1WithRSA(RSA)和SHA256WithRSA(RSA2)签名与验签】
作者QQ:(648437169) 点击下载➨Delphi支付宝支付 支付宝支付api文档 [Delphi支付宝支付]支持条码支付.扫码支付.交易查询.交易退款.退款查询.交易撤 ...
- Delphi RSA签名与验签【支持SHA1WithRSA(RSA1)、SHA256WithRSA(RSA2)和MD5WithRSA签名与验签】
作者QQ:(648437169) 点击下载➨ RSA签名与验签 [delphi RSA签名与验签]支持3种方式签名与验签(SHA1WithRSA(RSA1).SHA256WithRSA(RSA2)和M ...
- erlang的RSA签名与验签
1.RSA介绍 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对 其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而 ...
- RSA后台签名前台验签的应用(前台采用jsrsasign库)
写在前面 安全测试需要, 为防止后台响应数据返给前台过程中被篡改前台再拿被篡改后的数据进行接下来的操作影响正常业务, 决定采用RSA对响应数据进行签名和验签, 于是有了这篇<RSA后台签名前台验 ...
- 密码基础知识(2)以RSA为例说明加密、解密、签名、验签
密码基础知识(1)https://www.cnblogs.com/xdyixia/p/11528572.html 一.RSA加密简介 RSA加密是一种非对称加密.是由一对密钥来进行加解密的过程,分别称 ...
- PHP SHA1withRSA加密生成签名及验签
最近公司对接XX第三方支付平台的代付业务,由于对方公司只有JAVA的demo,所以只能根据文档自己整合PHP的签名加密,网上找过几个方法,踩到各种各样的坑,还好最后算是搞定了,话不多说,代码分享出来. ...
- 中行P1签名及验签
分享中国银行快捷.NET P1签名和验签方法代码中ReturnValue为自定义类型请无视 #region 验证签名 /// <summary> /// 验证签名 /// </sum ...
- 几个例子理解对称加密与非对称加密、公钥与私钥、签名与验签、数字证书、HTTPS加密方式
# 原创,转载请留言联系 为什么会出现这么多加密啊,公钥私钥啊,签名啊这些东西呢?说到底还是保证双方通信的安全性与完整性.例如小明发一封表白邮件给小红,他总不希望给别人看见吧.而各种各样的技术就是为了 ...
随机推荐
- [洛谷P4072] SDOI2016 征途
问题描述 Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路 ...
- java——解决"java.io.StreamCorruptedException: invalid stream header: xxx"
这个错误是由序列化引起的,可能的原因以及解决方法: 1.kryo对于集合(比如 Map)的反序列化会失效,报这个错误,解决办法比较暴力,不用kryo了,直接用java原生方法. 2.使用Java原生方 ...
- zTree 节点展开
var treeObj = $("#treeDemo"); $.fn.zTree.init(treeObj, setting, Znode1); zTree_Menu = $.fn ...
- CGI环境变量
所有的CGI程序都接收以下的环境变量,这些变量在CGI程序中发挥了重要的作用: 变量名 描述 CONTENT_TYPE 这个环境变量的值指示所传递来的信息的MIME类型.目前,环境变量CONTENT_ ...
- 直接选择排序(Straight Selection Sort)
1.定义 选择排序(Selection Sort)的基本思想是:每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,直到全部记录排序完毕. 常用的选择排序方法有直接选择排序和堆 ...
- Spring Boot教程(三十)使用Spring-data-jpa(1)
在实际开发过程中,对数据库的操作无非就“增删改查”.就最为普遍的单表操作而言,除了表和字段不同外,语句都是类似的,开发人员需要写大量类似而枯燥的语句来完成业务逻辑. 为了解决这些大量枯燥的数据操作语句 ...
- 如何在组件中监听vuex数据变化(当vuex中state变化时,子组件需要进行更新,怎么做?)
todo https://blog.csdn.net/qq_37899792/article/details/97640434
- 理解PyTorch的自动微分机制
参考Getting Started with PyTorch Part 1: Understanding how Automatic Differentiation works 非常好的文章,讲解的非 ...
- mongo 生命周期
监听MongoDB的生命周期,只需重写org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener的子类 ...
- C++入门经典-例3.14-使用while循环计算从1到10的累加
1:代码如下: // 3.14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...