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算法加解密的更多相关文章

  1. [Python3] RSA的加解密和签名/验签实现 -- 使用pycrytodome

    Crypto 包介绍: pycrypto,pycrytodome 和 crypto 是一个东西,crypto 在 python 上面的名字是 pycrypto 它是一个第三方库,但是已经停止更新,所以 ...

  2. RSA签名,加解密处理核心文件

    import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.secur ...

  3. php rsa 非对称加解密类

    <?php header("Content-Type: text/html;charset=utf-8"); /* 生成公钥.私钥对,私钥加密的内容能通过公钥解密(反过来亦可 ...

  4. 使用非对称算法RSA实现加解密和使用签名算法SHA1WithRSA、MD5withRSA生成签名以及验签

    不啰嗦,直接上源码 package com.hudai.platform.manager.util; import java.io.ByteArrayOutputStream; import java ...

  5. C# RSA 分段加解密

    RSA加解密: 1024位的证书,加密时最大支持117个字节,解密时为128:2048位的证书,加密时最大支持245个字节,解密时为256. 加密时支持的最大字节数:证书位数/8 -11(比如:204 ...

  6. .NET Core 使用RSA算法 加密/解密/签名/验证签名

    前言 前不久移植了支付宝官方的SDK,以适用ASP.NET Core使用支付宝支付,但是最近有好几位用户反应在Linux下使用会出错,调试发现是RSA加密的错误,下面具体讲一讲. RSA在.NET C ...

  7. Python rsa公私钥生成 rsa公钥加解密(分段加解密)-私钥加签验签实战

    一般现在的SAAS服务提供现在的sdk或api对接服务都涉及到一个身份验证和数据加密的问题.一般现在普遍的做法就是配置使用非对称加密的方式来解决这个问题,你持有SAAS公司的公钥,SAAS公司持有你的 ...

  8. RSA 分段加解密【解决“不正确的长度”的异常】

    RSA 是常用的非对称加密算法.最近使用时却出现了“不正确的长度”的异常,研究发现是由于待加密的数据超长所致. .NET Framework 中提供的 RSA 算法规定: 待加密的字节数不能超过密钥的 ...

  9. C# RSA的加解密与签名验证

    最近做了一个CS架构的序列号生成器,用到 RSA加解密技术,以下是RSA的使用方法 RSA加密算法是一种非对称加密算法.在公钥加密标准和电子商业中RSA被广泛使用.RSA是1977年由罗纳德•李维斯特 ...

随机推荐

  1. 论文笔记:Fast(er) RCNN

    在 RCNN 初步试水取得成功后,研究人员又迅速跟进,针对 RCNN 中的几点不足提出改进,接连推出了 fast-rcnn 和 faster-rcnn.关于这两篇论文,网上相关的文章实在是多如牛毛,因 ...

  2. AXI_DMA IP学习

    参考:PG201  AXI DMA v7.1    AXI IP核 功能:一旦处理器配置好传输方式之后,DMA可以自己完成内存数据的搬进或者搬出,而不需要处理器的介入.如果使用方法得当,DMA可以显著 ...

  3. Spring Cloud配置中心搭建(集成Git)

    1. 在Github(或其他)创建配置中心仓库bounter-config-repo,然后在仓库创建两个配置文件:simon.properties.susan.properties,链接如下: htt ...

  4. R语言数据类型

    R语言数据类型[转!!]Zhao-Pace  https://www.cnblogs.com/zhao441354231/p/5970544.html   R语言用来存储数据的对象包括: 向量, 因子 ...

  5. codeblocks 配置 opengl 编程宝典 的 gltools 环境

    懒得多说,亲测,这个问题,csdn 和 cnblog 上的博客真的没有一个能解决的. 这个帖子2L的答案则完美解决了问题,虽然步骤有些繁琐,过程还是英文,但考虑到了可能出现的各种问题,跟着走一遍就完美 ...

  6. 关于Integer比较问题

    public class Test { public static void main(String[] args) { Integer a=127; Integer b=127; System.ou ...

  7. json格式的中文输出显示

    print json.dumps(json.loads(result),ensure_ascii=False)

  8. TPshop之邮箱注册配置教程--附加常见问题集合

    ​ 准备:企业邮箱(开启POP/SMTP功能) 一.步骤教程: 1.登录企业邮箱(QQ邮箱示例) QQ邮箱 POP3:pop.qq.com SMTP:smtp.qq.com SMTP端口号:25 邮箱 ...

  9. AWS S3服务使用

    AWS S3是亚马逊的一种文件存储服务使用方便. 一.配置服务 public static class AWS_S3ClientInfo { private static readonly strin ...

  10. SQL SERVER 2012更改默认的端口号为1772

    打开开始菜单,找到sqlserver的配置管理器,点击打开 按下图配置右边窗口三项: 按下图配置右边三项: 按下图配置右边三项: 点击下图左边的SQL Server网络配置/MSSQLSERVER的协 ...