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字节,所以在加密和解密的过程中需要分块 ...
随机推荐
- zubax_gnss移植到STM32F407
源码下载:https://github.com/Zubax/zubax_gnss.git 源码默认支持STM32F107芯片 STM32 HAL库测试:zubax_gnss\bootloader\zu ...
- "Oracle要对Java收费了,SAP基于Java技术栈的那些产品的客户怎么办"
今年年初的时候,所谓"Oracle要对Java收费"的新闻,在网上传得沸沸扬扬.这个新闻被专业人士视为标题党,而国内众多技术论坛,比如知乎社区上,有很多大神对"Java收 ...
- Programmingbydoing
http://www.programmingbydoing.com/ 1. Modulus Animation public static void modulusAnimation() throws ...
- Python绘制拓扑图(无向图)、有向图、多重图。最短路径计算
前言: 数学中,“图论”研究的是定点和边组成的图形. 计算机中,“网络拓扑”是数学概念中“图”的一个子集.因此,计算机网络拓扑图也可以由节点(即顶点)和链路(即边)来进行定义和绘制. 延伸: 无向图 ...
- scrapy 用pycharm调试
1. 用pycharm打开scrapy项目,随便右击一个.py文件,选择Debug "***" 2. pycharm 右上角点击刚才debug的文件,选择Edit Configur ...
- [centos][yum] centos升级到特定版本
我们已知,yum upgrade命令可以将整个系统升级到最新版本. 但是很多时候,我们需要更新到指定版本,比如,当前最新的CentOS版本是7.6.1810 但是我需要更新到7.4,可以如下这样做: ...
- oracle更改数据库字符集
shutdown immediate; startup mount; alter system enable restricted session; alter system set job_queu ...
- 解决zabbix_web显示中文乱码问题
zabbix图形中文显示设置 如果想将zabbix的界面改成中文,点击类似于管理员头像,可以直接修改 检测中---图形,却显示乱码,这个问题是由于zabbix的web端没有中文字库,我们最需要把中文字 ...
- MySQL线程状态详解
前言: 我们常用 show processlist 或 show full processlist 查看数据库连接状态,其中比较关注的是 State 列,此列表示该连接此刻所在的状态.那么你真的了解不 ...
- selenium 全天课整理(二)
# encoding=utf-8 ''' selenium 全天 二 ''' #unittest例子 from selenium import webdriver import unittest,ti ...