java rsa 117_java实现RSA非对称加密解密
之前写过一篇java实现AES对称加密解密
在对密码加密传输的场景下 RSA非对称加密解密可能会更加适合。
原理就是后台生成一对公钥和私钥,公钥给前端用来加密,后台用私钥去解密,保证了传输过程中就算被截获也避免密码泄露。
下面是代码:
package com.zhaohy.app.utils;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
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.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class RSAUtil {
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* 获取密钥对
*
* @return 密钥对
*/
public static KeyPair getKeyPair() throws Exception {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(1024);
return generator.generateKeyPair();
}
/**
* 获取私钥
*
* @param privateKey 私钥字符串
* @return
*/
public static PrivateKey getPrivateKey(String privateKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
return keyFactory.generatePrivate(keySpec);
}
/**
* 获取公钥
*
* @param publicKey 公钥字符串
* @return
*/
public static PublicKey getPublicKey(String publicKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
return keyFactory.generatePublic(keySpec);
}
/**
* RSA加密
*
* @param data 待加密数据
* @param publicKey 公钥
* @return
*/
public static String encrypt(String data, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int inputLen = data.getBytes().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(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
// 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串
// 加密后的字符串
return new String(Base64.encodeBase64String(encryptedData));
}
/**
* RSA解密
*
* @param data 待解密数据
* @param privateKey 私钥
* @return
*/
public static String decrypt(String data, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] dataBytes = Base64.decodeBase64(data);
int inputLen = dataBytes.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(dataBytes, offset, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
// 解密后的内容
return new String(decryptedData, "UTF-8");
}
/**
* 签名
*
* @param data 待签名数据
* @param privateKey 私钥
* @return 签名
*/
public static String sign(String data, PrivateKey privateKey) throws Exception {
byte[] keyBytes = privateKey.getEncoded();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey key = keyFactory.generatePrivate(keySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(key);
signature.update(data.getBytes());
return new String(Base64.encodeBase64(signature.sign()));
}
/**
* 验签
*
* @param srcData 原始字符串
* @param publicKey 公钥
* @param sign 签名
* @return 是否验签通过
*/
public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {
byte[] keyBytes = publicKey.getEncoded();
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initVerify(key);
signature.update(srcData.getBytes());
return signature.verify(Base64.decodeBase64(sign.getBytes()));
}
/**
* 文件解密
*
* @param publicKeyStr
* @param srcFileName
* @param destFileName
*/
public static void decryptFileBig(String publicKeyStr, String srcFileName, String destFileName) {
Cipher cipher = null;
InputStream is = null;
OutputStream out = null;
try {
X509EncodedKeySpec encodedKey = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
KeyFactory keyf = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyf.generatePublic(encodedKey);
cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, pubKey);
File f = new File(srcFileName);
is = new FileInputStream(f);
out = new FileOutputStream(destFileName);
int blockSize = cipher.getBlockSize();
int size = Integer.valueOf(String.valueOf(f.length()));
byte[] decryptByte = new byte[size];
is.read(decryptByte);
//分别对各块数据进行解密
int j = 0;
while ((decryptByte.length - j * blockSize) > 0) {
out.write(cipher.doFinal(decryptByte, j * blockSize, blockSize));
j++;
}
} catch (Exception e) {
System.out.println(e);
} finally {
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 加密大文件
* @param privateKeyStr
* @param srcFileName
* @param destFileName
*/
public static void encryptFileBig(String privateKeyStr, String srcFileName, String destFileName) {
if (privateKeyStr == null) {
new Exception("加密私钥为空, 请设置");
}
Cipher cipher = null;
InputStream is = null;
OutputStream out = null;
CipherInputStream cis = null;
try {
// 使用默认RSA
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
Base64.decodeBase64(privateKeyStr));
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, priKey);
int blockSize = cipher.getBlockSize();
is = new FileInputStream(srcFileName);
File f = new File(srcFileName);
int size = Integer.valueOf(String.valueOf(f.length()));
byte[] encryptByte = new byte[size];
is.read(encryptByte);
out = new FileOutputStream(destFileName);
int outputBlockSize = cipher.getOutputSize(encryptByte.length);
int leavedSize = encryptByte.length % blockSize;
int blocksNum = leavedSize == 0 ? encryptByte.length / blockSize : encryptByte.length / blockSize + 1;
byte[] cipherData = new byte[blocksNum * outputBlockSize];
for (int i = 0; i < blocksNum; i++) {
if ((encryptByte.length - i * blockSize) > blockSize) {
cipher.doFinal(encryptByte, i * blockSize, blockSize, cipherData,i * outputBlockSize);
} else {
cipher.doFinal(encryptByte, i * blockSize, encryptByte.length - i * blockSize,cipherData, i * outputBlockSize);
}
}
out.write(cipherData);
} catch (Exception e) {
System.out.println(e);
} finally {
if (null != cis) {
try {
cis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* RSA文件签名
*
* @param filePath
* @param privateKey
* @param encode
* @return
*/
public static String signFile(String filePath, String privateKey, String encode) {
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader bfr = null;
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
java.security.Signature signature = java.security.Signature.getInstance("SHA1WithRSA");
signature.initSign(priKey);
fis = new FileInputStream(new File(filePath));
isr = new InputStreamReader(fis, encode);
bfr = new BufferedReader(isr);
String lineTxt = "";
while (!AppFrameworkUtil.isBlank(lineTxt = bfr.readLine())) {
signature.update(lineTxt.getBytes(encode));
}
byte[] signed = signature.sign();
String ret = new String(Base64.encodeBase64(signed));
System.out.println("signed:" + ret);
return ret;
} catch (Exception e) {
System.out.println(e);
} finally {
if (bfr != null) {
try {
bfr.close();
} catch (IOException e) {
}
}
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
}
}
}
return null;
}
/**
* RSA文件验签名检查
* @param content 待签名数据
* @param sign 签名值
* @param publicKey 分配给开发商公钥
* @param encode 字符集编码
* @return 布尔值
*/
public static boolean doCheckFile(String filePath, String sign, String publicKey, String encode) {
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader bfr = null;
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64.decodeBase64(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature.getInstance("SHA1WithRSA");
signature.initVerify(pubKey);
fis = new FileInputStream(new File(filePath));
isr = new InputStreamReader(fis, "UTF-8");
bfr = new BufferedReader(isr);
String lineTxt = "";
while (!AppFrameworkUtil.isBlank(lineTxt = bfr.readLine())) {
signature.update(lineTxt.getBytes(encode));
}
boolean bverify = signature.verify(Base64.decodeBase64(sign));
return bverify;
} catch (Exception e) {
System.out.println(e);
} finally {
if (bfr != null) {
try {
bfr.close();
} catch (IOException e) {
}
}
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
}
}
}
return false;
}
public static void main(String[] args) {
try {
// 生成密钥对
KeyPair keyPair = getKeyPair();
String privateKey = new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded()));
String publicKey = new String(Base64.encodeBase64(keyPair.getPublic().getEncoded()));
System.out.println("私钥:" + privateKey);
System.out.println("公钥:" + publicKey);
// RSA加密
String data = "123秘密啊";
String encryptData = encrypt(data, getPublicKey(publicKey));
System.out.println("加密后内容:" + encryptData);
// RSA解密
String decryptData = decrypt(encryptData, getPrivateKey(privateKey));
System.out.println("解密后内容:" + decryptData);
// RSA签名
String sign = sign(data, getPrivateKey(privateKey));
System.out.println("sign==" + sign);
// RSA验签
boolean result = verify(data, getPublicKey(publicKey), sign);
System.out.println("验签结果:" + result);
/****大文件加签验签****/
//加签验签
String fileSign = signFile("/home/zhaohy/Documents/test.doc", privateKey, "UTF-8");
System.out.println("fileSign==" + fileSign);
boolean checkFileBoolean = doCheckFile("/home/zhaohy/Documents/test.doc", fileSign, publicKey, "UTF-8");
System.out.println("大文件校验签名结果:" + checkFileBoolean);
//加密解密
encryptFileBig(privateKey, "/home/zhaohy/Documents/test.txt", "/home/zhaohy/Documents/test.dat");
decryptFileBig(publicKey, "/home/zhaohy/Documents/test.dat", "/home/zhaohy/Documents/test1.txt");
} catch (Exception e) {
e.printStackTrace();
System.out.print("加解密异常");
}
}
}
运行结果:
私钥:MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALpLjdbsu172ftiv3eUC/JghSSzNRlp8p9Ilr8XlK/gl3gaPFFo1BAHWWyb9MhoTdE5BvES6E/eW5gVKby8olLa6ILbh9UYif0SKWca7pTt2nqn2Cd8v29/94ZF9i+yMoime3wuS7QxJEHG7qCqps7KVNtP/4/628lq1jB6B3DrPAgMBAAECgYBUtCGrxTt0dBM8psn3ZKJA8XF6A2OnpOIRNL109zxEucL3rHqOgWhvBW2wjpMHNC0/n7fgb9LAUkYHxc5D3OmwXAhvgRzDmMTeoaikrLeJpxX9NQ4TU3CFcL9YabQ+rjB6yMgfbmmA0B/odxpzIZd6ypHq91ogI/rfP4McaX7NwQJBAO9Qm4SoOn/0SzfOE+PjnIyLkDqW2kFRJv+c/4Z0H/yPOIjytHhe6hQQ8KHT2azOP+SeAWbjb152a5Rp/E8da/8CQQDHSKDBSGZuN/Qyk1eGJ80T9+GSQI0oYQfZcHYNUkAKrWceHISL5jMrUXWHSlKjFC5E7RsqQKMn72xisrlLcXExAkEA7YAB11VdOT8opulNtAxfgNvA92RelhQDsAoPTVBRrkQ0xzSXBh6sD93/8ZpdnLHTlv94RLPSAt1jRpcoXxvD4QJBALtv00uYVkdqt3NuZE8ZVmlmp7KQpnQJN4HLpi2HZBbm2+tVdVHEVfJzbrCuNiWO0KohvYAzRYJFTlNSuLd93rECQDcgPHh0qBOW22ggxiqpfbLIURvPAT9urp8NuTM0K0rW3mC2me55yPSDQ7jL1t9vwYkfahc0GUl1V1Cq/449AHU=
公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6S43W7Lte9n7Yr93lAvyYIUkszUZafKfSJa/F5Sv4Jd4GjxRaNQQB1lsm/TIaE3ROQbxEuhP3luYFSm8vKJS2uiC24fVGIn9EilnGu6U7dp6p9gnfL9vf/eGRfYvsjKIpnt8Lku0MSRBxu6gqqbOylTbT/+P+tvJatYwegdw6zwIDAQAB
加密后内容:R7GqGE2r51PmJAt3wtKhsbqfFzeobvzqFlAp8Tv0+3HkevsUF2a+/ZO7Sn53cKGwXIkOkDQN0S/pk/Eacd8Wk1wXKTKx57eSaQJFv/HQ5nDUfvtMWIg0IcHNmHyNBfDPVe/MiMkKf23/a/EyEfCQEzsCQyHLyHoTg34a1SNXTLs=
解密后内容:123秘密啊
sign==p8JR0aserak6iPltfAJx/mlvlp5Ox5NcpvRo7R1rxDItekMhyF82RVizgMqsmEBpWzW9Qkxm6AWzjzEr+XhR7u4KhxEO7euTHC9NGJ0TAtDKqtAsfFaZi8ZyY4MkHnSCFZVMcWMR3GhZ8ALJGe/lSstNSEp8H9lQE8u2o2oYiiw=
验签结果:true
signed:aavuNSCwaT2jZ6XrlAbSJNLBDalkWZ1t0tnQnveUw+3exlpcvRu0xotAlrW0V4voLLeRydLgIjwCwq1YxqFyKcYlOuORzorlmihjSXBZf0GZoJIlTIaUZ8/TJV+CRFObFnnEQ+8QAbRs4b7AB6nv1A2bxMeKulS0OTPxSkSFTdM=
fileSign==aavuNSCwaT2jZ6XrlAbSJNLBDalkWZ1t0tnQnveUw+3exlpcvRu0xotAlrW0V4voLLeRydLgIjwCwq1YxqFyKcYlOuORzorlmihjSXBZf0GZoJIlTIaUZ8/TJV+CRFObFnnEQ+8QAbRs4b7AB6nv1A2bxMeKulS0OTPxSkSFTdM=
大文件校验签名结果:true
可以看到加密解密成功,里面最后加密解密文件自测只对txt或html等文本文件有效,doc或者excel加密文件后解密出来的东西乱码。
java rsa 117_java实现RSA非对称加密解密相关推荐
- java rsa内容超长_RSA 非对称加密解密,超长字符串分块处理
class RsaServer { /** * @var false|resource */ protected $key; /** * 分隔符 * @var string */ protected ...
- java的rsa作用_java 中RSA的方式实现非对称加密的实例
java 中rsa的方式实现非对称加密的实例 rsa通俗理解: 你只要去想:既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密:同理,既然是签名,那肯 ...
- CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互
(以下代码中都只做测试用,有些地方没有释放内存...这个自己解决下) 1.RSA非对称的,首先提供一个供测试用的证书和私钥的数据 1)pem格式的证书和私钥(公私钥是对应的)的base64编码 [cp ...
- Java DES、AES、RSA、DM5读取文件加密解密
//下面代码是直接读取文件来进行加密解密,算法文件 package Test; import javax.crypto.KeyGenerator; import javax.crypto.Cipher ...
- Java 实现RSA 签名/验签与加密解密
文章目录 一.前言 二.签名与验签 1.程序代码如下: 2.程序运行结果: 三.加密解密 1.添加加解密方法 2.程序运行结果 一.前言 RSA 算法相比于AES算法不同的是RSA的秘钥为不同的两个一 ...
- RSA非对称加密解密概念
1.RSA加密解密在线计算网站 网站1:https://www.bejson.com/enc/rsa/ 网站2:https://the-x.cn/cryptography/Rsa.aspx 2.PKC ...
- 工具类:登录密码的加解密(jsencrypt实现前端RSA非对称加密解密
定义工具类:utils/jsenscrypt.js import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'// 密钥对生成 http://web.cha ...
- daoi php_使用php生成RSA公钥私钥及进行加密解密和签名验证
这篇文章主要介绍使用PHP开发接口,数据实现RSA加密解密后使用,实例分析了PHP自定义RSA类实现加密与解密的技巧,非常具有实用价值,需要的朋友可以参考下. 简单介绍RSA: RSA加密算法是最常用 ...
- RSA实现对文件的加密解密
很多示例只能加密小文件 这个可以加密大点的文件 文件越大加解密时间越长 package com.harp.oa.utils;import org.bouncycastle.jce.provider.B ...
最新文章
- CTC损失函数 Transformer用的
- 消控中心人员配置_建筑能耗监测系统集中化运行管理模式和人员配置!
- 云栖掠影|回首开源十年,RocketMQ 焕发新生
- android黑窗口获取md5_Android获取文件的MD5
- 网络OS显神威 认识Linux远程桌面控制
- 怎么查看我的php版本,怎样查看php版本
- python treeview显示多列_Python Gtk TreeView列数据显示
- 非常全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了!
- [转]2020年4月github上最热门项目-java
- Android:强制EditText删除焦点? [重复]
- ios12上滑关闭程序动画_iOS 12.3正式版终于来了:这类用户升级需谨慎!
- 基于隐式调用风格的kwic实现
- UI设计中金刚区图标设计总结
- 在民间借贷软件开发中用到的电子文档存储技术
- Monte Carlo Algorithms
- 信息学奥赛一本通评测系统P1332
- 263企业邮箱imap服务器,263企业邮箱支持IMAP邮箱搬家功能
- win10在电脑中添加新用户
- 100个RPA经典应用场景解析
- 2019数据安装勾选_天正T20V5.0建筑安装包免费下载附安装教程
热门文章
- 【渝粤教育】国家开放大学2018年春季 0599-21T工程造价管理基础理论与相关法规 参考试题
- 【渝粤教育】 国家开放大学2020年春季 2246社会工作概论 参考试题
- 【渝粤教育】电大中专建设工程法规 (2)作业 题库
- 【渝粤题库】陕西师范大学151203 初级会计学作业(笔试题型)
- 蓝桥杯基础模块3_1:数码管静态显示
- python找答案__学小易找答案
- 用ajax写无限循环,ajax无限循环
- 循环自相关函数和谱相关密度(四)——实信号、复信号模型下的QPSK信号循环谱推导
- 循环自相关函数和谱相关密度(三)——实信号、复信号模型下的BPSK信号循环谱MATLAB仿真结果及代码
- Java基本语法(13)--条件分支switch-case结构