java使用RSA与AES加密解密的实例代码详解

网友投稿 412 2023-01-03


java使用RSA与AES加密解密的实例代码详解

首先了解下,什么是堆成加密,什么是非对称加密?

对称加密:加密与解密的密钥是相同的,加解密速度很快,比如AES

非对称加密:加密与解密的秘钥是不同的,速度较慢,比如RSA

•先看代码(先会用在研究)

相关依赖:

org.bouncycastle

bcprov-jdk15on

1.58

1,RSA工具类:

package cn.wangtao.utils;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;

import java.io.ByteArrayOutputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectOutputStream;

import java.security.*;

import java.security.interfaces.RSAPrivateKey;

import java.security.interfaces.RSAPublicKey;

/**

* @ClassName RSAUtils

* @Auth 桃子

* @Date 2019-6-25 15:15

* @Version 1.0

* @Description

**/

public class RSAUtils {

private static final String RSA = "RSA"; // 加密方式

private static final Logger logger= LoggerFactory.getLogger(RSAUtils.class);

//获取密钥

public static KeyPair getKey() throws Exception {

try {

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA, new BouncyCastleProvider());

keyPairGenerator.initialize(2048); // 初始化密钥长度

KeyPair keyPair = keyPairGenerator.generateKeyPair();// 生成密钥对

return keyPair;

} catch (Exception e) {

logger.error("获取RSA秘钥对异常",e);

throw new Exception("获取RSA秘钥对异常",e);

}

}

//利用公钥进行加密

public static String encryptStr(RSAPublicKey publicKey, String str) throws Exception {

try {

Cipher cipher = Cipher.getInstance(RSA, new BouncyCastleProvider());

cipher.init(Cipher.ENCRYPT_MODE, publicKey);

//加密

byte[] bytes = getBytes(str.getBytes(), cipher);

//2进行转换成16进制

String result = CommonUtils.parseByte2HexStr(bytes);

return result;

} catch (Exception e) {

logger.error("使用RSA公钥进行加密异常",e);

throw new Exception("使用RSA公钥进行加密异常",e);

}

}

//利用私钥进行解密

public static String decryptStr(RSAPrivateKey privateKey, String str) throws Exception {

try {

Cipher cipher = Cipher.getInstance(RSA, new BouncyCastleProvider());

cipher.init(Cipher.DECRYPT_MODE, privateKey); // 用密钥初始化此Cipher对象

//16进制转换成2进制

byte[] bytes = CommonUtils.parseHexStr2Byte(str);

//解密

byte[] bs = getBytes(bytes, cipher);

String content=new String(bs,"utf-8");

return content;

} catch (Exception e) {

logger.error("使用RSA私钥进行解密异常",e);

throw new Exception("使用RSA私钥进行解密异常",e);

}

}

//通过cipher获取字节数组

public static byte[] getBytes(byte[] bytes,Cipher cipher) throws Exception {

int blockSize = cipher.getBlockSize(); // 返回块的大小

int j = 0;

ByteArrayOutputStream baos = new ByteArrayOutputStream();

while (bytes.length - j * blockSize > 0) { // 将二进制数据分块写入ByteArrayOutputStream中

if(bytes.length-j*blockSize>blockSize){

baos.write(cipher.doFinal(bytes, j * blockSize, blockSize));

}else{

baos.write(cipher.doFinal(bytes, j * blockSize,bytes.length-j*blockSize));

}

j++;

}

baos.close();

byte[] byteArray = baos.toByteArray();

return byteArray;

}

//保存秘钥对到文件

public void saveRSAKey(String fileName) throws Exception {

FileOutputStream fos=null;

ObjectOutputStream oos=null;

try {

KeyPair keyPair = getKey();

fos=new FileOutputStream(fileName);

oos=new ObjectOutputStream(fos); //对象序列号

oos.writeObject(keyPair);

} catch (Exception e) {

logger.error("RSA秘钥对保存到文件异http://常[{}]",fileName,e);

throw new Exception("RSA秘钥对保存到文件异常",e);

}finally {

if(oos!=null){

try {

oos.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

if(fos!=null){

try {

fos.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

}

}

2,CommonUtils通用工具类:

package cn.wangtao.utils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import java.io.IOException;

import java.io.Reader;

import java.io.Writer;

/**

* @ClassName CommonUtils

* @Auth 桃子

* @Date 2019-6-27 12:51

* @Version 1.0

* @Description

**/

public class CommonUtils {

private static final Logger logger= LoggerFactory.getLogger(CommonUtils.class);

//编码方式

public static final String CODE_TYPE = "UTF-8";

//字符补全

private static final String[] consult = new String[]{"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G"};

//关流

public static void closeReaderandWriter(Reader reader, Writer writer){

if(writer!=null){

try {

writer.close();

} catch (IOException e) {

logger.error("关闭输出流失败",e);

}

}

if(reader!=null){

try {

reader.close();

} catch (IOException e) {

logger.error("关闭输出流失败",e);

}

}

}

//将16进制转换为二进制

public static byte[] parseHexStr2Byte(String hexStr) {

if (hexStr.length() < 1)

return null;

byte[] result = new byte[hexStr.length()/2];

for (int i = 0;i< hexStr.length()/2; i++) {

int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);

int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);

result[i] = (byte) (high * 16 + low);

}

return result;

}

//将二进制转换成16进制

public static String parseByte2HexStr(byte buf[]) {

StringBuffer sb = new StringBuffer();

for (int i = 0; i < buf.length; i++) {

String hex = Integer.toHexString(buf[i] & 0xFF);

if (hex.length() == 1) {

hex = '0' + hex;

}

sb.append(hex.toUpperCase());

}

return sb.toString();

}

//补全字符

public static String completionCodeFor16Bytes(String str) throws Exception {

try{

int num = str.getBytes(CODE_TYPE).length;

int index = num%16;

//进行加密内容补全操作, 加密内容应该为 16字节的倍数, 当不足16*n字节是进行补全, 差一位时 补全16+1位

//补全字符 以 $ 开始,$后一位代表$后补全字符位数,之后全部以0进行补全;

if(index != 0){

StringBuffer sbBuffer = new StringBuffer(str);

if(16-index == 1){

sbBuffer.append("$" + consult[16-1] + addStr(16-1-1));

}else{

sbBuffer.append("$" + consult[16-index-1] + addStr(16-index-1-1));

}

str = sbBuffer.toString();

}

return str;

}catch (Exception e){

logger.error("使用AES加密前补全字符异常",e);

throw new Exception("使用AES加密前补全字符异常",e);

}

}

//追加字符

public static String addStr(int num){

StringBuffer sbBuffer = new StringBuffer("");

for (int i = 0; i < num; i++) {

sbBuffer.append("0");

}

return sbBuffer.toString();

}

//还原字符(进行字符判断)

public static String resumeCodeOf16Bytes(String str) throws Exception{

int indexOf = str.lastIndexOf("$");

if(indexOf == -1){

return str;

}

String trim = str.substring(indexOf+1,indexOf+2).trim();

int num = 0;

for (int i = 0; i < consult.length; i++) {

if(trim.equals(consult[i])){

num = i;

}

}

if(num == 0){

return str;

}

return str.substring(0,indexOf).trim();

}

}

3,AESUtils通用工具类:

package cn.wangtao.utils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;

import javax.crypto.spec.SecretKeySpec;

import java.io.*;

import java.security.interfaces.RSAPrivateKey;

import java.util.Map;

/**

* @ClassName AESUtils

* @Auth 桃子

* @Date 2019-6-27 12:05

* @Version 1.0

* @Description

**/

public class AESUtils {

private static final Logger logger= LoggerFactory.getLogger(AESUtils.class);

//填充类型

public static final String AES_TYPE = "AES/ECB/PKCS5Padding";

private static final String AES = "AES"; // 加密方式

public static final String DES_TYPE = "DES/ECB/PKCS5Padding";

private static final String DES = "DES"; // 加密方式

private final String defaultDesKey="11112222";//8位

//对字符串加密

public static String encryptStr(String content,String aesKey) throws Exception {

try {

SecretKeySpec key = new SecretKeySpec(aesKey.getBytes(),AES );

Cipher cipher = Cipher.getInstance(AES_TYPE);

cipher.init(Cipher.ENCRYPT_MODE, key);

//字符补全

String content16Str = CommonUtils.completionCodeFor16Bytes(content);

byte[] encryptedData = cipher.doFinal(content16Str.getBytes(CommonUtils.CODE_TYPE));

//2进制转换成16进制

String hexStr = CommonUtils.parseByte2HexStr(encryptedData);

return hexStr;

} catch (Exception e) {

logger.error("使用AES对字符串加密异常",e);

throw new Exception("使用AES对字符串加密异常",e);

}

}

//对字符串解密

public static String decryptStr(String content,String aesKey) throws Exception {

try {

//16进制转换成2进制

byte[] bytes = CommonUtils.parseHexStr2Byte(content);

SecretKeySpec key = new SecretKeySpec(

aesKey.getBytes(), AES);

Cipher cipher = Cipher.getInstance(AES_TYPE);

cipher.init(Cipher.DECRYPT_MODE, key);

byte[] decryptedData = cipher.doFinal(bytes);

String result=new String(decryptedData, CommonUtils.CODE_TYPE);

//还原字符

String orgResult = CommonUtils.resumeCodeOf16Bytes(result);

return orgResult;

} catch (Exception e) {

logger.error("使用AES对字符串解密异常",e);

throw new Exception("使用AES对字符串解密异常",e);

}

}

//对文件加密

public static File encryptFile(File orgFile, File encryptFile, Map context) throws Exception {

logger.info("使用AES对文件加密开始,源文件地址[{}]加密后文件地址[{}]",orgFile.getPath(),encryptFile.getPath());

BufferedReader br=null;

BufferedWriter bw=null;

try{

//获取AESKEY ,如果没有为默认

String aesKey = (String) context.get(Dirt.AES_KEY);

br=new BufferedReader(new FileReader(orgFile));

bw=(BufferedWriter)context.get(Dirt.BUFFEREDWRITER);

if(null==bw){

bw=new BufferedWriter(new FileWriter(encryptFile));

}

String len=null;

while (null!=(len=br.readLine())){

String encrypt= encryptStr(len,aesKey);

bw.write(encrypt);

bw.newLine();

bw.flush();

}

logger.info("使用AES对文件加密结束,源文件地址[{}]加密后文件地址[{}]",orgFile.getPath(),encryptFile.getPath());

return encryptFile;

}catch (Exception e){

logger.error("使用AES对文件加密异常,源文件地址[{}]加密后文件地址[{}]",orgFile.getPath(),encryptFile.getPath(),e);

throw new Exception("使用AES对文件加密异常",e);

}finally {

CommonUtils.closeReaderandWriter(br,bw);

}

}

//对文本解密,返回解密文件后的文件

public static File decryptFile(File decryptfile, File encryptFile,Map context) throws Exception {

logger.info("使用AES对文件解密开始,源加密文件地址[{}]解密后文件地址[{}]",encryptFile.getPath(),decryptfile.getPath());

BufferedReader br=null;

BufferedWriter bw=null;

try{

if(decryptfile.exists()){

decryptfile.delete();

}

//边读边加密边写

br=new BufferedReader(new FileReader(encryptFile));

bw=new BufferedWriter(new FileWriter(decryptfile));

String len=null;

String aesKey=null;

//判断是否加密

RSAPrivateKey privateKey= (RSAPrivateKey) context.get(Dirt.RSAPRIVATEKEY);

if(null!=privateKey){

StringBuffer sb=new StringBuffer();

while ((len=br.readLine())!=null){

sb.append(len);

if(len.equals("\n")||len.equals("")||len.equals("\r\n")||len.equals("\r")){

aesKey=RSAUtils.decryptStr(privateKey,sb.toString());

break;

}

}

}

if(null==aesKey){

aesKey=(String) context.get(Dirt.AES_KEY);

}

logger.info("aesKey[{}]",aesKey);

if(aesKey!=null){

while ((len=br.readLine())!=null){

String decrypt= decryptStr(len,aesKey);

bw.write(decrypt);

bw.flush();

bw.newLine();

}

}

logger.info("使用AES对文件解密结束,源加密文件地址[{}]解密后文件地址[{}]",encryptFile.getPath(),decryptfile.getPath());

return decryptfile;

}catch (Exception e){

logger.error("使用AES对文件解密异常,源加密文件地址[{}]解密后文件地址[{}]",encryptFile.getPath(),decryptfile.getPath(),e);

throw new Exception("使用AES对文件解密异常",e);

}finally {

CommonUtils.closeReaderandWriter(br,bw);

}

}

}

4,Dirt常量

package cn.wangtao.utils;

import java.security.interfaces.RSAPublicKey;

/**

* @ClassName Dirt

* @Auth 桃子

* @Date 2019-6-27 14:20

* @Version 1.0

* @Description

**/

public class Dirt {

public static final String UPLOADFILEURL="uploadFileUrl";

public static final String AES_KEY="aesKey";

public static final String RSAPUBLICKEY="rsaPublicKey";

public static final String RSAPRIVATEKEY="rsaPrivateKey";

public final static String RETURNCODE="returnCode";

public final static String RETURNMSG="returnMsg";

public final static String FILENAME="fileName";

public final static String ORGFILENAME="orgFileName";

public final static String ENCRYPTFILE="encryptFile";

public static final String BUFFEREDWRITER="bufferedWriter"; //是为了在原始文件中进行补充加密

//返回码

public final static String SUCCESSCODE="000000";

public final static String FAILEDCODE="999999";

//加密文件所放的目录

public final static String BASELOCALDIR="XXX"; //基本目录路径

public final static String ENCRYPTLOCALDIR="encrypt"; //加密文件目录

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:单片机硬件接口测试工具(硬件测试用什么工具)
下一篇:教务系统接口设计报告(教务系统接口设计报告模板)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~