RSA算法加解密
package org.thcic.ejw.util.encrypt; import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map; import javax.crypto.Cipher; /**
* <p>
* RSA公钥/私钥/签名工具包
* </p>
* <p>
* 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
* </p>
*
*/
public class RSAUtils {
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA"; /**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey"; /**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey"; /**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117; /**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128; private static final String CONVERT_CHARSET = "UTF-8";
private static final String PADDING_MODE = "RSA/ECB/PKCS1Padding"; /**
* <p>
* 生成密钥对(公钥和私钥)
* </p>
*
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(512);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
} /**
* <p>
* 用私钥对信息生成数字签名
* </p>
*
* @param data 已加密数据
* @param privateKey 私钥(BASE64编码)
*
* @return
* @throws Exception
*/
public static String sign(String data, String privateKey) throws Exception {
byte[] dataBytes = data.getBytes(CONVERT_CHARSET);
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(dataBytes);
return Base64Utils.encode(signature.sign());
} /**
* <p>
* 校验数字签名
* </p>
*
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
*
* @return
* @throws Exception
*
*/
public static boolean verify(String data, String publicKey, String sign)
throws Exception {
byte[] dataBytes = data.getBytes(CONVERT_CHARSET);
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(dataBytes);
return signature.verify(Base64Utils.decode(sign));
} /**
* <P>
* 私钥解密
* </p>
*
* @param encryptedData 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static String decryptByPrivateKey(String encryptedData, String privateKey)
throws Exception {
byte[] encryptedDataBytes=Base64Utils.decode(encryptedData);
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(PADDING_MODE);
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedDataBytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedDataBytes, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedDataBytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedDataBytes = out.toByteArray();
out.close();
return new String(decryptedDataBytes, CONVERT_CHARSET);
} /**
* <p>
* 公钥解密
* </p>
*
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static String decryptByPublicKey(String encryptedData, String publicKey)
throws Exception {
byte[] encryptedDataBytes = Base64Utils.decode(encryptedData);
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(PADDING_MODE);
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedDataBytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedDataBytes, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedDataBytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedDataBytes = out.toByteArray();
out.close();
return new String(decryptedDataBytes, CONVERT_CHARSET);
} /**
* <p>
* 公钥加密
* </p>
*
* @param data 源数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static String encryptByPublicKey(String data, String publicKey)
throws Exception {
byte[] dataBytes = data.getBytes(CONVERT_CHARSET);
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(PADDING_MODE);
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = dataBytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(dataBytes, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedDataBytes = out.toByteArray();
out.close();
return Base64Utils.encode(encryptedDataBytes);
} /**
* <p>
* 私钥加密
* </p>
*
* @param data 源数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static String encryptByPrivateKey(String data, String privateKey)
throws Exception {
byte[] dataBytes = data.getBytes(CONVERT_CHARSET);
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(PADDING_MODE);
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = dataBytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(dataBytes, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedDataBytes = out.toByteArray();
out.close();
return Base64Utils.encode(encryptedDataBytes);
} /**
* <p>
* 获取私钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64Utils.encode(key.getEncoded());
} /**
* <p>
* 获取公钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64Utils.encode(key.getEncoded());
} //测试
public static void main(String[] args) throws Exception {
Map<String, Object> aa=genKeyPair();
String pubkey=getPublicKey(aa);
System.out.println(PUBLIC_KEY+":"+pubkey);
String prikey=getPrivateKey(aa);
System.out.println(PRIVATE_KEY+":"+prikey);
String sign=sign("dwlhjt2018", prikey);
System.out.println("sign:"+sign);
boolean verify=verify("dwlhjt2018", pubkey, sign);
System.out.println("verify:"+verify);
String token="d3e88280437eb5731232c1a06067491d";
String bb=encryptByPublicKey(token, pubkey);
System.out.println("token密文:"+bb);
String cc=decryptByPrivateKey(bb, prikey);
System.out.println("token:"+cc);
String dd=encryptByPrivateKey("10347289823923874", prikey);
System.out.println("data密文:"+dd);
String ee=decryptByPublicKey(dd, pubkey);
System.out.println("data:"+ee);
} }
RSA算法加解密的更多相关文章
- [Python3] RSA的加解密和签名/验签实现 -- 使用pycrytodome
Crypto 包介绍: pycrypto,pycrytodome 和 crypto 是一个东西,crypto 在 python 上面的名字是 pycrypto 它是一个第三方库,但是已经停止更新,所以 ...
- RSA签名,加解密处理核心文件
import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.secur ...
- php rsa 非对称加解密类
<?php header("Content-Type: text/html;charset=utf-8"); /* 生成公钥.私钥对,私钥加密的内容能通过公钥解密(反过来亦可 ...
- 使用非对称算法RSA实现加解密和使用签名算法SHA1WithRSA、MD5withRSA生成签名以及验签
不啰嗦,直接上源码 package com.hudai.platform.manager.util; import java.io.ByteArrayOutputStream; import java ...
- C# RSA 分段加解密
RSA加解密: 1024位的证书,加密时最大支持117个字节,解密时为128:2048位的证书,加密时最大支持245个字节,解密时为256. 加密时支持的最大字节数:证书位数/8 -11(比如:204 ...
- .NET Core 使用RSA算法 加密/解密/签名/验证签名
前言 前不久移植了支付宝官方的SDK,以适用ASP.NET Core使用支付宝支付,但是最近有好几位用户反应在Linux下使用会出错,调试发现是RSA加密的错误,下面具体讲一讲. RSA在.NET C ...
- Python rsa公私钥生成 rsa公钥加解密(分段加解密)-私钥加签验签实战
一般现在的SAAS服务提供现在的sdk或api对接服务都涉及到一个身份验证和数据加密的问题.一般现在普遍的做法就是配置使用非对称加密的方式来解决这个问题,你持有SAAS公司的公钥,SAAS公司持有你的 ...
- RSA 分段加解密【解决“不正确的长度”的异常】
RSA 是常用的非对称加密算法.最近使用时却出现了“不正确的长度”的异常,研究发现是由于待加密的数据超长所致. .NET Framework 中提供的 RSA 算法规定: 待加密的字节数不能超过密钥的 ...
- C# RSA的加解密与签名验证
最近做了一个CS架构的序列号生成器,用到 RSA加解密技术,以下是RSA的使用方法 RSA加密算法是一种非对称加密算法.在公钥加密标准和电子商业中RSA被广泛使用.RSA是1977年由罗纳德•李维斯特 ...
随机推荐
- 2018-2019-2 网络对抗技术 20165325 Exp1 PC平台逆向破解
2018-2019-2 网络对抗技术 20165325 Exp1 PC平台逆向破解(BOF实验) 实验有三个模块: (一)直接修改程序机器指令,改变程序执行流程: (二)通过构造输入参数,造成BOF攻 ...
- MUI上传图片之选择相册和相机上传
1.因为项目中有三处地方需要上传,所以html中存在三处地方.身份证正反面为上传一张,发票限制上传9张. <div class="action1"> <!--展示 ...
- 初学python之路-day09
今天的主要内容为内存管理. 1.引用计数:垃圾回收机制的依据 # 1.变量的值被引用,该值的引用计数 +1 # 2.变量的值被解绑,该值的引用计数 -1 # 3.引用计数为0时就会被垃圾回收机制回收 ...
- gardner 算法matlab实现
% 仿真4比特原始数据与星座图的编码映射过程: % 完成16QAM信号的调制解调: % 基带信号符号速率 ps =1Mbps: % 成形滤波器的滚降因子 a=0.8: % 载波信号频率fc=2MHz ...
- ubuntu快速部署gitlab汉化容器
前言:gitlab的原理我就不扯了(看这个https://www.jianshu.com/p/567207ac51cd),下面直接上操作 1.前提: a.要有docker的运行环境,用service ...
- vapor 生成xcode project 产生的错误解决方式
运行vapor xcode时报错: Could not generate Xcode project: error: terminated(72): xcrun --sdk macosx --find ...
- Windows下安装Redis客户端
Redis是有名的NoSql数据库,一般Linux都会默认支持.但在Windows环境中,可能需要手动安装设置才能有效使用.这里就简单介绍一下Windows下Redis服务的安装方法,希望能够帮到你. ...
- Mybatis 源码学习系列
前言 很久以前,我们学习了Java,从一个控制台的 Hello world .开始,我们进入了面向对象的世界. 然后由学习了SQL语言,可以写出SQL语句来将尘封在硬盘之下的数据库数据,展现出来. 后 ...
- docker 安装kafka
1.下载镜像这里使用了wurstmeister/kafka和wurstmeister/zookeeper这两个版本的镜像 docker pull wurstmeister/zookeeperdocke ...
- codeforces 1110F
题解: 正解做法比较简单,考虑离线之后,相邻两个节点之间的答案是有关系的 发现从父亲移到儿子后,改变的距离对于当前节点子树内和子树外的是一样的 所以线段树维护一下区间加减取max就可以了 另外的做法1 ...