package com.example.demo.ras;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Properties;
/**
* @author Created by deli
* @date 2018/9/21 09:04
* @description TODO
*/
public class RsaEncryptUtil {
/** */
/**
* 加密算法RSA
*/
public static final StringKEY_ALGORITHM ="RSA";// RSA/ECB/PKCS1Padding
/**
* String to hold name of the encryption padding.
*/
public static final StringPADDING ="RSA/NONE/PKCS1Padding";// RSA/NONE/NoPadding
/**
* String to hold name of the security provider.
*/
public static final StringPROVIDER ="BC";
/** */
/**
* 签名算法
*/
public static final StringSIGNATURE_ALGORITHM ="MD5withRSA";
/** */
/**
* 获取公钥的key
*/
private static final StringPUBLIC_KEY ="rsa_public_key";
/** */
/**
* 获取私钥的key
*/
private static final StringPRIVATE_KEY ="rsa_private_pkcs8";
/** */
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK =117;
/** */
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK =128;
/*
* 公钥加密
*/
public static StringencryptByPublicKey(String str)throws Exception {
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(PADDING, PROVIDER);
// 获得公钥
Key publicKey =getPublicKey();
// 用公钥加密
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// 读数据源
byte[] data = str.getBytes("UTF-8");
int inputLen = data.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, offSet, MAX_ENCRYPT_BLOCK);
}else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i *MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return Base64Util.encode(encryptedData);
}
/**
* 私钥加密
*
* @param str
* @return
* @throws Exception
* @comment
*/
public static StringencryptByPrivateKey(String str)throws Exception {
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(PADDING, PROVIDER);
// 获得私钥
Key privateKey =getPrivateKey();
// 用私钥加密
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
// 读数据源
byte[] data = str.getBytes("UTF-8");
int inputLen = data.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, offSet, MAX_ENCRYPT_BLOCK);
}else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i *MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return Base64Util.encode(encryptedData);
}
/*
* 公钥解密
*/
public static StringdecryptByPublicKey(String str)throws Exception {
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(PADDING, PROVIDER);
// 获得公钥
Key publicKey =getPublicKey();
// 用公钥解密
cipher.init(Cipher.DECRYPT_MODE, publicKey);
// 读数据源
byte[] encryptedData = Base64Util.decode(str);
int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
}else {
cache = cipher
.doFinal(encryptedData, 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");
}
/*
* 私钥解密
*/
public static StringdecryptByPrivateKey(String str)throws Exception {
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(PADDING, PROVIDER);
// 得到Key
Key privateKey =getPrivateKey();
// 用私钥去解密
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// 读数据源
byte[] encryptedData = Base64Util.decode(str);
int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
}else {
cache = cipher
.doFinal(encryptedData, 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");
}
/**
* 从文件中读取公钥
*
* @return
* @throws Exception
* @comment
*/
private static KeygetPublicKey()throws Exception {
/* InputStream stream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("rsa_key.properties");
Properties properties = new Properties();
properties.load(stream);
String key = properties.getProperty(PUBLIC_KEY);*/
String key ="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjZOyTvf/HrHFveCwTxuqRMWZswid5ArI2/e62rkBlORZma7T7TCRrjUnZl/4zF3NB8XRuNFCfhmIHfWcdv8bSQFn5EuiJTv1rav/jMQEXhPzdAU2t3vT7uZg9m1HDjQAvTNex8+9epzi2qIb4Rk+rY6RCZTOu7y/ILHfTcAue0wIDAQAB";
byte[] keyBytes;
keyBytes = Base64Util.decode(key);
X509EncodedKeySpec keySpec =new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
/**
* 从文件中读取公钥String
*
* @return
* @throws Exception
* @comment
*/
public static StringgetStringPublicKey()throws Exception {
InputStream stream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("rsa_key.properties");
Properties properties =new Properties();
properties.load(stream);
String key = properties.getProperty(PUBLIC_KEY);
return key;
}
/**
* 获取私钥
*
* @return
* @throws Exception
* @comment
*/
private static KeygetPrivateKey()throws Exception {
/* InputStream stream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("rsa_key.properties");
Properties properties = new Properties();
properties.load(stream);
String key = properties.getProperty(PRIVATE_KEY);*/
//String key = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAONk7JO98escW94LBPG6pExZmzCJ3kCsjb97rauQGU5FmZrtPtMJGuNSdmXjMXc0HxdG40UJ+GYgd9Zx2xtJAWfkS6IlOWtq+MxAReEN0BTa3e9Pu5mD2bUcONAC9M17Hz716nOLaohvhGT6tjpEJlM67vL8gsd9NwC57TAgMBAAECgYA0SdrUxlXwtkiHV1zbV1xM8s0YqTSmcOZGGvIvc7YEHeEKbQ+LO4bBSw8KuU7HmNUgI9DYChB5obYLguGVFATJRo6o57ZVuRjOqp7WynF9fy5sFetlG9ZXCrI+kmlFjVd58n11fMYh4YbxiybcxrxZ7eYjy59Z4U6QXCfoQUQJBAPx7WScV3Znfa4PF7fjZXAL0cGpxHlT7c0EP4Y584TeH2dPy6cWExJlK9MtWgbxPGfEr8FF3vPOWONdoZEUCQQDmkBVjuuxUi2IMUr7Bm3nK0rs6nYvosFJsuk6Ia5ryqkhesWz6dsktxtbzyl5d1AycRMSPumDTBG1oS0YKQQ3AkB75I85bPjEMYyWErJBOfor0gGg1GOBAFvWLqm79KYLDqQja93EKbsLOcPbj6yD2hD5CIPFx+K6oW2xe1Ijno9AkBfmmk0JGMwn2c1ou30S+rRnlYCdSd5gfuDdgVdlGFxJAjEMx0L2M2NxgUmNpOX8om1iEHVAooFdLkBypwwA7AkAkPI2b1D83Tjel3FVY0+vkx4CJBNSYnjPpBhgTgrpsi6+L0rnGy0JcWK9cf69wUVOeeU2V31nIcRHHxv0e";
String key="MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAO6UnZMIadbZnDQ9\n" +
"o7YQLinGcHV8JVhmfET1rv0pmp9wGnHEYNW1wK4ko95+Ehpb0y8a5xtu4gGn/X1k\n" +
"SngP5t5q9WTnjxR4T0dboMeUJrRMXUK7nroTFj2IaLTGDGfQYDXCFTctDp5ZgTkU\n" +
"W73Fx27I7YiXyz5Gc2oLbLiFW1rBAgMBAAECgYEAqGl0CfRocedOonnYdI5bZ9XS\n" +
"ULx/yDUgB7W9/qs9oMqLgD91c6ZHCyaGHmqz8LNdEeVVukG9fBnPkJIZF0NyXbXb\n" +
"NXEUasOHt0YHhMRZ0v8QSs3fcWNTiwqUcJ9r7m2pBtS19JEDVqWQ/3K+KBqcbZ3T\n" +
"VqKTAV3N0oxpqUPRgVkCQQD/oY77Ws3difIjNYtdsNkMqU46FE1vA/4TmY5s07ne\n" +
"4LmktE1pTBCmzwbZS/LWwj0Q8w5JPxhfi2LICj+fLCY3AkEA7uzB/Rra13Niqy71\n" +
"LtIS2LazVxtg0RDwnIhu/BBlHG5zCntvQ+6ah/0sFvkcZYQXfM6MeAqG6hCno7x8\n" +
"NhCKxwJBAL0La0PzSR82rrzfEiu9ZyZ35oQJE6Kv3yv7eVp90Y1Dv8ZQGJdwSzgx\n" +
"Di2QfwvXJXXtaXk9kfbGi8zH13kNG00CQQCadIYH2NeGlro/jfDE3tt+K8YOVs2k\n" +
"+f2CRBTzcKnc0m4eZaONV++gYAOjqlE4M0d30JMweyWypSeqiwwFa3Y7AkAWzB2C\n" +
"WW27MV4N/U1FvEEIl2+nDAuuTwVUoSNAkldaKpk8go7LlAQKkmDt7roJmMOnQgUy\n" +
"PuN97iVXfyl0KHVH";
byte[] keyBytes;
keyBytes = Base64Util.decode(key);
PKCS8EncodedKeySpec keySpec =new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
}
package com.example.demo.ras;
import it.sauronsoftware.base64.Base64;
import java.io.*;
/**
* @author Created by deli
* @date 2018/9/21 09:05
* @description TODO
*/
public class Base64Util {
/** */
/**
* 文件读取缓冲区大小
*/
private static final int CACHE_SIZE =1024;
/** */
/**
*
* BASE64字符串解码为二进制数据
*
*
* @param base64
* @return
* @throws Exception
*/
public static byte[]decode(String base64)throws Exception {
return Base64.decode(base64.getBytes());
}
/** */
/**
*
* 二进制数据编码为BASE64字符串
*
*
* @param bytes
* @return
* @throws Exception
*/
public static Stringencode(byte[] bytes)throws Exception {
return new String(Base64.encode(bytes));
}
/** */
/**
*
* 将文件编码为BASE64字符串
*
*
* 大文件慎用,可能会导致内存溢出
*
*
* @param filePath
* 文件绝对路径
* @return
* @throws Exception
*/
public static StringencodeFile(String filePath)throws Exception {
byte[] bytes =fileToByte(filePath);
return encode(bytes);
}
/** */
/**
*
* BASE64字符串转回文件
*
*
* @param filePath
* 文件绝对路径
* @param base64
* 编码字符串
* @throws Exception
*/
public static void decodeToFile(String filePath, String base64)
throws Exception {
byte[] bytes =decode(base64);
byteArrayToFile(bytes, filePath);
}
/** */
/**
*
* 文件转换为二进制数组
*
*
* @param filePath
* 文件路径
* @return
* @throws Exception
*/
public static byte[]fileToByte(String filePath)throws Exception {
byte[] data =new byte[0];
File file =new File(filePath);
if (file.exists()) {
FileInputStream in =new FileInputStream(file);
ByteArrayOutputStream out =new ByteArrayOutputStream(2048);
byte[] cache =new byte[CACHE_SIZE];
int nRead =0;
while ((nRead = in.read(cache)) != -1) {
out.write(cache, 0, nRead);
out.flush();
}
out.close();
in.close();
data = out.toByteArray();
}
return data;
}
/** */
/**
*
* 二进制数据写文件
*
*
* @param bytes
* 二进制数据
* @param filePath
* 文件生成目录
*/
public static void byteArrayToFile(byte[] bytes, String filePath)
throws Exception {
InputStream in =new ByteArrayInputStream(bytes);
File destFile =new File(filePath);
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}
destFile.createNewFile();
OutputStream out =new FileOutputStream(destFile);
byte[] cache =new byte[CACHE_SIZE];
int nRead =0;
while ((nRead = in.read(cache)) != -1) {
out.write(cache, 0, nRead);
out.flush();
}
out.close();
in.close();
}
}
网友评论