RSA签名和验签Util
目录
- 1、DigitalSign类
- 2、CryptException异常类
- 3、加签示例
- 4、验签示例
1、DigitalSign类
import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;/*** 证书加解密/签名/验签类*/
public class DigitalSign {private static DigitalSign single=null;/** 编码 格式*/private static String encoding = "UTF-8";/** 算法 */private String arithmetic = "SHA1withRSA";/**私钥缓存**/private ConcurrentHashMap<String, RSAPrivateCrtKey> map = new ConcurrentHashMap<String, RSAPrivateCrtKey>();private DigitalSign(String encoding){}private DigitalSign(){}/*** 初始化 实例*/public static synchronized void init() { if (single == null) { single = new DigitalSign(encoding); } }/*** 初始化 实例*/public static synchronized void init(String charset) {if (single == null) {single = new DigitalSign();encoding = charset;}}//静态工厂方法 public static DigitalSign getInstance() {if (single == null) { init(); //为空的时候同步实例} return single; }//静态工厂方法public static DigitalSign getInstance(String charset) {if (single == null) {init(charset); //为空的时候同步实例}return single;}/*** 私钥签名 * @param tobeSigned* @param priKeyPath classpath 下路径* @param password* @return* @throws CryptException*/public String SignMsgByRelativePath(final String tobeSigned, final String priKeyPath, final String password) throws CryptException {RSAPrivateCrtKey priKey = getPriKeyByRelativePath(priKeyPath, password);return sign(priKey, tobeSigned);}/*** 私钥签名* @param tobeSigned* @param priKeyStream 私钥文件流* @param password* @return* @throws CryptException*/public String SignMsgByInputStream(String tobeSigned,InputStream priKeyStream,String password) throws CryptException{RSAPrivateCrtKey priKey = getPriKeyByInputStream(priKeyStream, password);return sign(priKey, tobeSigned);}/*** 私钥签名* @param tobeSigned* @param priKeyPath 私钥绝对路径* @param password* @return* @throws CryptException*/public String signMsgByAbsolutePath(String tobeSigned,String priKeyPath,String password) throws CryptException{RSAPrivateCrtKey priKey = map.get(priKeyPath);if(priKey == null){priKey = getPriKeyByAbsolutePath(priKeyPath, password);}return sign(priKey, tobeSigned);}/*** 私钥签名* @param tobeSigned* @param priKeyPath 私钥绝对路径* @param password* @return* @throws CryptException*/public String signMsgByAbsolutePath(Map<String, Object> tobeSigned,String priKeyPath,String password) throws CryptException{RSAPrivateCrtKey priKey = map.get(priKeyPath);if(priKey == null){priKey = getPriKeyByAbsolutePath(priKeyPath, password);}return sign(priKey, tobeSigned);}/*** 公钥验签 * @param tobeVerfied* @param plainText* @param pubKey 文件输入流* @return* @throws CryptException*/public boolean verifyMsgByInputSteam(String tobeVerfied,String plainText,InputStream pubKey) throws CryptException{//获取公钥RSAPublicKey pubkey = getPubKeyByInputSteam(pubKey);return verify(pubkey, tobeVerfied, plainText);}/*** 通过公钥验签* @param tobeVerified* @param plainText* @param pubkeyPath 公钥绝对路径* @return* @throws CryptException*/public boolean verifyMsgByAbsolutePath(String tobeVerified,String plainText,String pubkeyPath) throws CryptException{RSAPublicKey pubkey = getPubKeyByAbsolutePath(pubkeyPath);return verify(pubkey, tobeVerified, plainText);}/*** 通过公钥验签* @param tobeVerified* @param map* @param pubkeyPath 公钥绝对路径* @return* @throws CryptException*/public boolean verifyMsgByAbsolutePath(String tobeVerified,Map<String, Object> map,String pubkeyPath) throws CryptException{RSAPublicKey pubkey = getPubKeyByAbsolutePath(pubkeyPath);return verify(pubkey, tobeVerified, map);}/*** 公钥验签* @param tobeVerfied* @param plainText* @param CertFile 文件classpath下路径* @return* @throws CryptException*/public boolean verifyMsgByRelativePath(String tobeVerfied, String plainText, String CertFile) throws CryptException {RSAPublicKey pubkey = getPubKeyByRelativePath(CertFile);return verify(pubkey, tobeVerfied, plainText);}/*** 使用公钥对数据加密* @param TobeEncryptMsg 待加密的明文字符串* @param certFile 公钥路径[相对地址 classpath下]* @return 加密后的字符串* @throws CryptException 错误信息*/public String encryptMsg(String TobeEncryptMsg, String certFile) throws CryptException {//获取公钥RSAPublicKey pubKey = getPubKeyByRelativePath(certFile);Cipher instance;try {instance = Cipher.getInstance(pubKey.getAlgorithm());instance.init(Cipher.ENCRYPT_MODE, pubKey);String encryMsg = Base64.encodeBase64String(instance.doFinal(Base64.encodeBase64(TobeEncryptMsg.getBytes(encoding))));return encryMsg;} catch (Exception e) {throw new CryptException("加密失败",e);}} /*** 私钥解密* @param TobeDecodeMsg 待解密的加密字符串* @param priFile 私钥路径[相对路径 classpath下]* @param passWord 私钥密码* @return 解密后的明文字符串* @throws CryptException 错误信息*/public String decodeMsg(String TobeDecodeMsg, String priFile,String passWord) throws CryptException{RSAPrivateCrtKey priKey = getPriKeyByRelativePath(priFile, passWord);Cipher instance;try {instance = Cipher.getInstance(priKey.getAlgorithm());instance.init(Cipher.DECRYPT_MODE, priKey);String string = new String(Base64.decodeBase64(instance.doFinal(Base64.decodeBase64(TobeDecodeMsg))), encoding);return string;} catch (Exception e) {throw new CryptException("解密失败",e);}}/*** 获取私钥 文件流* @param keyfileStream* @param password* @return* @throws CryptException*/private RSAPrivateCrtKey getPriKeyByInputStream(InputStream keyfileStream,String password) throws CryptException{return getPriKey(keyfileStream, password); }/*** 通过文件绝对路径加载私钥* @param priKeyPath 绝对路径* @param password* @return* @throws CryptException*/private RSAPrivateCrtKey getPriKeyByAbsolutePath(String priKeyPath,String password) throws CryptException{FileInputStream file;try {file = new FileInputStream(priKeyPath);} catch (FileNotFoundException e) {throw new CryptException("秘钥路径不正确",e);}RSAPrivateCrtKey priKey = getPriKey(file, password);map.put(priKeyPath, priKey);return priKey;}/*** 获取私钥 [classpath]* @param KeyFile* @param passWord* @return*/private RSAPrivateCrtKey getPriKeyByRelativePath(String KeyFile,String passWord) throws CryptException{//获取项目 相对路径ClassLoader cl = DigitalSign.class.getClassLoader();InputStream fiKeyFile = cl.getResourceAsStream(KeyFile);return getPriKey(fiKeyFile, passWord);}/*** 获取公钥 [文件输入流]* @param pubKey* @return* @throws CryptException*/private RSAPublicKey getPubKeyByInputSteam(InputStream pubKey) throws CryptException{return getPublicKey(pubKey);}/*** 获取公钥 [classpath下]* @param CertFile* @return*/private RSAPublicKey getPubKeyByRelativePath(String CertFile) throws CryptException{//读取公钥文件ClassLoader cl = DigitalSign.class.getClassLoader();InputStream certfile = cl.getResourceAsStream(CertFile);//获取公钥return getPublicKey(certfile);}/*** 获取公钥 通过绝对路径* @param pubKeyPath* @return* @throws CryptException*/private RSAPublicKey getPubKeyByAbsolutePath(String pubKeyPath) throws CryptException{try{FileInputStream pubKey = new FileInputStream(pubKeyPath);return getPublicKey(pubKey);}catch(Exception e){throw new CryptException("文件读取失败",e);}}/*** 获取公钥* @param pubKey 公钥流* @return* @throws CryptException*/private RSAPublicKey getPublicKey(InputStream pubKey) throws CryptException{X509Certificate x509cert = null;try {//实例化 x509CertificateFactory cf = CertificateFactory.getInstance("X.509");x509cert = (X509Certificate) cf.generateCertificate(pubKey);} catch (CertificateException e) {if (pubKey != null){try {pubKey.close();} catch (IOException e1) {throw new CryptException("文件流关闭异常",e1);}} throw new CryptException("初始化公钥异常",e);}//读取公钥RSAPublicKey pubkey = (RSAPublicKey) x509cert.getPublicKey(); return pubkey;}/*** 获取私钥* @param priKey* @param keyPassword* @return* @throws CryptException*/private RSAPrivateCrtKey getPriKey(InputStream priKey,String keyPassword) throws CryptException{String keyAlias = null;RSAPrivateCrtKey prikey = null; try {KeyStore ks = KeyStore.getInstance("PKCS12");ks.load(priKey, keyPassword.toCharArray());Enumeration<?> myEnum = ks.aliases();while (myEnum.hasMoreElements()) {keyAlias = (String) myEnum.nextElement();if (ks.isKeyEntry(keyAlias)) {prikey = (RSAPrivateCrtKey) ks.getKey(keyAlias, keyPassword.toCharArray());break;}} } catch (Exception e) {if (priKey != null){try {priKey.close();} catch (IOException e1) {throw new CryptException("流关闭异常",e1);}}throw new CryptException("加载私钥失败",e);}if(prikey == null){throw new CryptException("私钥不存在");}return prikey; }/*** 签名* @param priKey 私钥* @param tobeSigned 待签字符串* @return 签名结果* @throws CryptException*/private String sign(RSAPrivateCrtKey priKey,String tobeSigned) throws CryptException{try {Signature sign = Signature.getInstance(arithmetic);sign.initSign(priKey); sign.update(tobeSigned.getBytes(encoding)); byte signed[] = sign.sign();
// byte sign_asc[] = new byte[signed.length * 2];
// Hex2Ascii(signed.length, signed, sign_asc);// return new String(signed,encoding); return Base64.encodeBase64String(signed).replaceAll("\\+", "%2B");} catch (Exception e) {throw new CryptException("签名失败",e);} }/*** 签名* @param priKey 私钥* @param map 待签字符串* @return 签名结果* @throws CryptException*/private String sign(RSAPrivateCrtKey priKey,Map<String, Object> map) throws CryptException{try {String tobeSigned = appendMap(map);Signature sign = Signature.getInstance(arithmetic);sign.initSign(priKey);sign.update(tobeSigned.getBytes(encoding));byte signed[] = sign.sign();
// byte sign_asc[] = new byte[signed.length * 2];
// Hex2Ascii(signed.length, signed, sign_asc);// return new String(signed,encoding);return Base64.encodeBase64String(signed).replaceAll("\\+", "%2B");} catch (Exception e) {throw new CryptException("签名失败",e);}}/*** 连接参数* @param map* @return*/private static String appendMap(Map<String, Object> map){Set<String> keySet = map.keySet();StringBuilder sb = new StringBuilder();for (String mapKey : keySet){String value = (String)map.get(mapKey);sb.append(mapKey).append("=").append(value).append("&");}return sb.toString();}/*** 验证签名* @param pubkey 公钥* @param tobeVerfied 已签名字符串* @param plainText 待校验字符串* @return true || false* @throws CryptException*/private boolean verify(RSAPublicKey pubkey,String tobeVerfied,String plainText) throws CryptException{try {Signature verify = Signature.getInstance(arithmetic);verify.initVerify(pubkey);
// byte signeddata[] = new byte[tobeVerfied.length() / 2];
// Ascii2Hex(tobeVerfied.length(), tobeVerfied.getBytes(encoding), signeddata); verify.update(plainText.getBytes(encoding)); return verify.verify(Base64.decodeBase64(tobeVerfied.replaceAll("%2B", "\\+")));} catch (Exception e) {throw new CryptException("验签失败",e);} }/*** 验证签名* @param pubkey 公钥* @param tobeVerfied 已经签名的map* @param map 待校验的map* @return true || false* @throws CryptException*/private boolean verify(RSAPublicKey pubkey,String tobeVerfied,Map<String, Object> map) throws CryptException{try {String plainText = appendMap(map);Signature verify = Signature.getInstance(arithmetic);verify.initVerify(pubkey);
// byte signeddata[] = new byte[tobeVerfied.length() / 2];
// Ascii2Hex(tobeVerfied.length(), tobeVerfied.getBytes(encoding), signeddata);verify.update(plainText.getBytes(encoding));return verify.verify(Base64.decodeBase64(tobeVerfied.replaceAll("%2B", "\\+")));} catch (Exception e) {throw new CryptException("验签失败",e);}}
}
2、CryptException异常类
/*** 密钥异常类*/
public class CryptException extends Exception{private static final long serialVersionUID = 2843021655596315128L;public CryptException(String message){super(message);}public CryptException(String message, Throwable cause) {super(message, cause);}public CryptException(Throwable cause) {super(cause);}
}
3、加签示例
Map<String, String> map = new TreeMap<String, String>();
//....省略map put值...
String sign = DigitalSign.getInstance().signMsgByAbsolutePath(map, path,
password);
map.put("sign", sign);
4、验签示例
map.remove("sign");
DigitalSign digitalSign = DigitalSign.getInstance();
boolean result = digitalSign.verifyMsgByAbsolutePath(sign, params, merchCertPath);
转载于:https://www.cnblogs.com/ranandrun/p/DigitalSign.html
RSA签名和验签Util相关推荐
- .NET Core RSA 签名和验签(密钥为 16 进制编码)
使用 OpenSSL 生成公私钥对,命令: $ openssl genrsa -out rsa_1024_priv.pem$ openssl pkcs8 -topk8 -inform PEM -in ...
- C++ 使用OpenSSL 基于SHA1摘要的RSA签名及验签 与Java平台互通
文章目录 准备 C++ Java RSASignature.java RSAEncrypt.java Base64.java 准备 配置OpenSSL环境 配置VS2015环境 生成公私秘钥 然后你们 ...
- 微信小程序-RSA签名、验签、加密、解密
title: [小程序]RSA签名 type: categories date: 2017-05-27 17:01:15 categories: 小程序 tags: [RSA, 签名] 一个适用于微信 ...
- PHP实现RSA签名和验签
<?php define('ICLOD_CERT_PATH',dirname(__FILE__).'/xx_pri.key' ); //私钥文件 define('ICLOD_CERT_PUBLI ...
- iOS小技能:RSA签名、验签、加密、解密的原理
文章目录 引言 I RSA算法流程 1.1 算法原理 1.2 公钥和私钥的生成 1.3 RSA 加密 1.4 RSA 解密 1.5 RSA加密.签名区别 1.6 RSA签名的过程 II 代码实现 2. ...
- 使用RSA、MD5对参数生成签名与验签
在日常的工作中,我们对外提供的接口或调用三方的接口往往有一步生成签名或验签的步骤,这个步骤主要是验证调用方是 不是合法的以及内容是否被修改.比如:对于某些网上公开下载的软件,视频,尤其是镜像文件.如果 ...
- 支付宝签名与验签,return_url和通知页notify_url
1 支付宝签名与验签 签名与验签的作用 首先了解下使用RSA签名与验签的作用是什么? 对数据进行签名后,可以保证数据完整性,机密性和发送方角色的不可抵赖性,可以有效防止请求信息信息被篡改. 以商户服务 ...
- 分享一个RSA加解密工具类,公钥加密私钥解密、私钥加密公钥解密、私钥签名公钥验签、生成公钥私钥
测试: public static void main(String[] args) {try {//生成公钥私钥Map<String, Object> map = RSAUtil.ini ...
- ASP VBSCRIPT VBA RSA 公钥加密 私钥解密 私钥签名 公钥验签
<% '@title: Class_Crypt_Rsa '@author: ekede.com '@date: 2020-10-28 '@description: RSA 公钥加密->私钥 ...
- asp版 vbscript RSA公钥加密 / 私钥解密 / 私钥签名 / 公钥验签(支持中文)分段加密解密
最近有空在把自己的asp站点后端函数全部整理了下,在弄RSA的时候遇到了坑了,然后找到下面这位兄弟刚好发布的文章: https://blog.csdn.net/todaygods/article/de ...
最新文章
- java 性能检测工具 检测死锁等
- 机器学习笔记 network compression
- java 如何去掉http debug日志_你居然还去服务器上捞日志,搭个日志收集系统难道不香吗?...
- linux内核那些事之mmap
- [ESC] EnTT 学习记录 2
- c++11 随机数random
- Arthas实践--快速排查Spring Boot应用404/401问题
- 20世纪50年代开始,数字技术出现,数字计算机开始代替模拟计算机,我们从电气时代逐渐走到了信息时代,电脑重塑了社会的架构与价值。...
- 大家有什么n刷的小说,可以推荐一下吗?
- BAT机器学习面试1000题系列(第1~305题)
- linux编译mmplay,mplay编译与移植
- 全国高校计算机能力挑战赛赛事通知
- 三国志战略版:北定中原剧本个性加点指引
- 腾讯云短信服务(SMS)申请流程
- 【前端面试指南】简历上的前端常用单词,你拼写对了吗?
- 让猴子游泳,让鸭子爬树
- 【算法】常见数据结构基本算法整理
- HeapCreate()
- 逐步解析力扣846. 一手顺子 (贪心)
- python执行cmd命令,并获得返回值