Spring boot RSA 文件加密解密
github项目地址 rsa_demo
测试
加密D:/hello/test.pdf 文件,生成加密后的文件 testNeedDecode.pdf
对testNeedDecode.pdf 文件进行解密,生成testFinal.pdf 文件
package com.lick.controller;
import java.util.Map;
import static com.lick.util.RSAUtils.*;
public class RSATest {
public static void main(String[] args) throws Exception {
Map<String, Object> initKey = initKey();
String publicKeyStr = getPublicKeyStr(initKey);
String privateKeyStr = getPrivateKeyStr(initKey);
encryptFile("D:/hello/test.pdf","D:/hello/testNeedDecode.pdf",publicKeyStr);
decryptFile("D:/hello/testNeedDecode.pdf","D:/hello/testFinal.pdf",privateKeyStr);
}
}
添加依赖
<!-- 替换sun.misc.BASE64Encoder -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
RSAUtils.java
package com.lick.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.*;
import java.security.*;
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;
public class RSAUtils {
public static final String KEY_ALGORITHM = "RSA";
private static final String PUBLIC_KEY = "RSAPublicKey";
private static final String PRIVATE_KEY = "RSAPrivateKey";
public static final String SIGNATURE_ALGORITHM="MD5withRSA";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
public static Map<String, Object> initKey() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
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;
}
//获得公钥字符串
public static String getPublicKeyStr(Map<String, Object> keyMap) throws Exception {
//获得map中的公钥对象 转为key对象
Key key = (Key) keyMap.get(PUBLIC_KEY);
//编码返回字符串
return encryptBASE64(key.getEncoded());
}
//获得私钥字符串
public static String getPrivateKeyStr(Map<String, Object> keyMap) throws Exception {
//获得map中的私钥对象 转为key对象
Key key = (Key) keyMap.get(PRIVATE_KEY);
//编码返回字符串
return encryptBASE64(key.getEncoded());
}
//获取公钥
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes;
// keyBytes = (new BASE64Decoder()).decodeBuffer(key);
keyBytes = Base64.decodeBase64(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
//获取私钥
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
// keyBytes = (new BASE64Decoder()).decodeBuffer(key);
keyBytes = Base64.decodeBase64(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
//解码返回byte
public static byte[] decryptBASE64(String key) throws Exception {
// return (new BASE64Decoder()).decodeBuffer(key);
return Base64.decodeBase64(key);
}
//编码返回字符串
public static String encryptBASE64(byte[] key) throws Exception {
// return (new BASE64Encoder()).encodeBuffer(key);
return Base64.encodeBase64String(key);
}
//***************************签名和验证*******************************
public static byte[] sign(byte[] data,String privateKeyStr) throws Exception{
PrivateKey priK = getPrivateKey(privateKeyStr);
Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initSign(priK);
sig.update(data);
return sig.sign();
}
public static boolean verify(byte[] data,byte[] sign,String publicKeyStr) throws Exception{
PublicKey pubK = getPublicKey(publicKeyStr);
Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initVerify(pubK);
sig.update(data);
return sig.verify(sign);
}
//************************加密解密**************************
public static byte[] encrypt(byte[] plainText,String publicKeyStr)throws Exception{
PublicKey publicKey = getPublicKey(publicKeyStr);
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int inputLen = plainText.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
int i = 0;
byte[] cache;
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(plainText, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(plainText, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptText = out.toByteArray();
out.close();
return encryptText;
}
public static byte[] decrypt(byte[] encryptText,String privateKeyStr)throws Exception{
PrivateKey privateKey = getPrivateKey(privateKeyStr);
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
int inputLen = encryptText.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(encryptText, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptText, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] plainText = out.toByteArray();
out.close();
return plainText;
}
//************************加密文件**************************
public static void encryptFile(String inputPath, String outputPath, String publicKeyStr) throws Exception {
try {
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom();
keygen.init(random);
SecretKey key = keygen.generateKey();
PublicKey publicKey = getPublicKey(publicKeyStr);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.WRAP_MODE, publicKey);
byte[] wrappedKey = cipher.wrap(key);
DataOutputStream out = new DataOutputStream(new FileOutputStream(outputPath));
out.writeInt(wrappedKey.length);
out.write(wrappedKey);
InputStream in = new FileInputStream(inputPath);
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
crypt(in, out, cipher);
in.close();
out.close();
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//************************解密文件**************************
public static void decryptFile(String inputPath, String outputPath, String privateKeyStr) throws Exception {
try {
DataInputStream in = new DataInputStream(new FileInputStream(inputPath));
int length = in.readInt();
byte[] wrappedKey = new byte[length];
in.read(wrappedKey, 0, length);
PrivateKey privateKey = getPrivateKey(privateKeyStr);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.UNWRAP_MODE, privateKey);
Key key = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);
OutputStream out = new FileOutputStream(outputPath);
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
crypt(in, out, cipher);
in.close();
out.close();
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//对数据分段加密解密
public static void crypt(InputStream in, OutputStream out, Cipher cipher) throws IOException, GeneralSecurityException {
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
byte[] inBytes = new byte[blockSize];
byte[] outBytes = new byte[outputSize];
int inLength = 0;
boolean next = true;
while (next) {
inLength = in.read(inBytes);
if (inLength == blockSize) {
int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
out.write(outBytes, 0, outLength);
} else {
next = false;
}
}
if (inLength > 0) {
outBytes = cipher.doFinal(inBytes, 0, inLength);
} else {
outBytes = cipher.doFinal();
}
out.write(outBytes);
}
}
Spring boot RSA 文件加密解密的更多相关文章
- Spring Boot 配置文件密码加密两种方案
Spring Boot 配置文件密码加密两种方案 jasypt 加解密 jasypt 是一个简单易用的加解密Java库,可以快速集成到 Spring 项目中.可以快速集成到 Spring Boot 项 ...
- Spring cloud config配置文件加密解密
Spring cloud config配置文件加密解密 学习了:http://blog.csdn.net/u010475041/article/details/78110349 学习了:<Spr ...
- 峰哥说技术:06-手撸Spring Boot自定义启动器,解密Spring Boot自动化配置原理
Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 06 峰哥说技术:手撸Spring Boot自定义启动器,解密Spring Boot自动化配置原理 Sp ...
- linux环境下给文件加密/解密的方法
原文地址:linix环境下给文件加密/解密的方法 作者:oracunix 一. 利用 vim/vi 加密:优点:加密后,如果不知道密码,就看不到明文,包括root用户也看不了:缺点:很明显让别人知 ...
- Spring Boot入门——文件上传与下载
1.在pom.xml文件中添加依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="ht ...
- 51. spring boot属性文件之多环境配置【从零开始学Spring Boot】
原本这个章节是要介绍<log4j多环境不同日志级别的控制的>但是没有这篇文章做基础的话,学习起来还是有点难度的,所以我们先一起了解下spring boot属性文件之多环境配置,当然文章中也 ...
- spring boot:单文件上传/多文件上传/表单中多个文件域上传(spring boot 2.3.2)
一,表单中有多个文件域时如何实现说明和文件的对应? 1,说明和文件对应 文件上传页面中,如果有多个文件域又有多个相对应的文件说明时, 文件和说明如何对应? 我们在表单中给对应的file变量和text变 ...
- Spring Boot 实现配置文件加解密原理
Spring Boot 配置文件加解密原理就这么简单 背景 接上文<失踪人口回归,mybatis-plus 3.3.2 发布>[1] ,提供了一个非常实用的功能 「数据安全保护」 功能,不 ...
- RSA算法加密解密
该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1. jar 注意:RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块 ...
随机推荐
- ubuntu 使用alias 新增删除命令del替代rm
alias del=trash #del命令别名删除文件至回收站 alias lt='ls /tmp' #lt命令显示回收站中的文件 alias cle=cleartrash #cle清除tmp文件夹 ...
- UCOSIII互斥信号量
互斥信号量可以解决优先级反转问题 优化后现象 优化方法:L和H等待同一个信号量的时候,将L任务优先级提至H相同优先级 实验举例 void start_task(void *p_arg) { OS_CR ...
- JavaScript仿百度图片浏览效果(转载)
转载来源:https://www.jb51.net/article/98030.htm 这是一个非常好的案例,然而jquery的时代正在徐徐关闭. 当你调整浏览器宽高,你会发现它不是自适应的.当你想把 ...
- TypeScript_基础数据类型
TypeScript 的基础数据类型包含: string.number.boolean.array .object.null.undefined.enmu.void.never.any.tuple 注 ...
- HashMap,HashSet
HashMap,HashSet 摘自:https://www.cnblogs.com/skywang12345/p/3310887.html#a1 目录 一. HashMap(键值对形式存取,键 ...
- Centos7.4(阿里云环境)挂载数据盘
Centos7.4(阿里云环境)挂载数据盘 2018.08.29 10:19 947浏览 查看数据盘 disk -l 磁盘 /dev/vda:42.9 GB, 42949672960 字节,83886 ...
- 批处理引擎MapReduce编程模型
批处理引擎MapReduce编程模型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. MapReduce是一个经典的分布式批处理计算引擎,被广泛应用于搜索引擎索引构建,大规模数据处理 ...
- Fiddler使用资料-整理
以下是一个博主写的一个系列. 随笔分类 - Fiddler 10.Fiddler中设置断点修改Response 摘要:当然Fiddler中也能修改Response 第一种:打开Fiddler 点击 ...
- 创建htpasswd文件在nginx (没有 apache)
Create htpasswd file for nginx (without apache) APACHE NGINX HTACCESS If you're like me, and use Ngi ...
- k8s安装之etcd备份还原yaml
etcd备份还原方案,这种比较高级. 使用docker,自动化处理. 如果单节点备份,ETCD_ENDPOINTS一个即可. 如果多节点恢复,依次执行恢复脚本即可. apiVersion: batch ...