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

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

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

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

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

  相关依赖:

<dependency>
   <groupId>org.bouncycastle</groupId>
   <artifactId>bcprov-jdk15on</artifactId>
   <version>1.58</version>
 </dependency>

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秘钥对保存到文件异常[{}]",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<String,Object> 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<String,Object> 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"; //加密文件目录

 总结

以上所述是小编给大家介绍的java使用RSA与AES加密解密的实例代码详解 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • Java使用AES加密和解密的实例详解

    Java使用AES加密和解密的实例详解 前言: AES的基本要求是,采用对称分组密码体制,密钥长度的最少支持为128.192.256,分组长度128位,算法应易于各种硬件和软件实现.1998年NIST开始AES第一轮分析.测试和征集,共产生了15个候选算法.1999年3月完成了第二轮AES2的分析.测试.2000年10月2日美国政府正式宣布选中比利时密码学家Joan Daemen 和 Vincent Rijmen 提出的一种密码算法RIJNDAEL 作为 AES. 在应用方面,尽管DES在安全上

  • JAVA 中解密RSA算法JS加密实例详解

    JAVA 中解密RSA算法JS加密实例详解 有这样一个需求,前端登录的用户名密码,密码必需加密,但不可使用MD5,因为后台要检测密码的复杂度,那么在保证安全的前提下将密码传到后台呢,答案就是使用RSA非对称加密算法解决 . java代码 需要依赖 commons-codec 包 RSACoder.Java import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import java.security.

  • Java加密解密和数字签名完整代码示例

    常见的加密算法 基本的单向加密算法: BASE64严格地说,属于编码格式,而非加密算法 MD5(MessageDigestalgorithm5,信息摘要算法) SHA(SecureHashAlgorithm,安全散列算法) HMAC(HashMessageAuthenticationCode,散列消息鉴别码) 复杂的对称加密(DES.PBE).非对称加密算法: DES(DataEncryptionStandard,数据加密算法) PBE(Password-basedencryption,基于密码

  • Java RSA加密解密实现方法分析【附BASE64 jar包下载】

    本文实例讲述了Java RSA加密解密实现方法.分享给大家供大家参考,具体如下: 该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar javabase64-1.3.1.jar 本站下载地址. 注意: RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块进行. RSA加密对明文的长度是有限制的,如果加密数据过大会抛出如下异常: Exception in thread "main" javax.cryp

  • 常用数字签名算法RSA与DSA的Java程序内实现示例

    RSA加密算法 我们来回顾一下RSA的加密算法.我们从公钥加密算法和签名算法的定义出发,用比较规范的语言来描述这一算法. RSA公钥加密体制包含如下3个算法:KeyGen(密钥生成算法),Encrypt(加密算法)以及Decrypt(解密算法). 密钥生成算法以安全常数作为输入,输出一个公钥PK,和一个私钥SK.安全常数用于确定这个加密算法的安全性有多高,一般以加密算法使用的质数p的大小有关.越大,质数p一般越大,保证体制有更高的安全性.在RSA中,密钥生成算法如下:算法首先随机产生两个不同大质

  • Java AES加密解密的简单实现方法

    废话不多说,直接上代码 package com.mstf.aes; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.crypto.BadPaddingException; import

  • RSA加密算法java简单实现方法(必看)

    简单完整的代码,通过这个代码你将对RSA加密算法在Java中的实现方法有一个初步的了解,这个类,你可以直接使用,水平高的,就自己修改完善下代码. package security; import java.security.*; import java.security.spec.*; import java.security.interfaces.*; import javax.crypto.spec.*; import javax.crypto.interfaces.*; import ja

  • java实现的AES加密算法完整实例

    本文实例讲述了java实现的AES加密算法.分享给大家供大家参考,具体如下: import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import android.util.Base64; /** * @author vipin.cb , vipin.cb@experionglobal.com <br> * Sep 27, 2013

  • java利用Apache commons codec进行MD5加密,BASE64加密解密,执行系统命令

    编写代码之前先来介绍一下我们要用到的两个包; commons-codec-1.10.jar Commons项目中用来处理常用的编码方法的工具类包,例如DES.SHA1.MD5.Base64,URL,Soundx等等. commons-exec-1.3.jar Apache Commons Exec 是 Apache 上的一个 Java 项目,提供一些常用的方法用来执行外部进程 你可以到本站直接下载 Apache Commons 官方包 下面看一下代码结构: import org.apache.c

  • java加密算法分享(rsa解密、对称加密、md5加密)

    复制代码 代码如下: import java.io.UnsupportedEncodingException;import java.security.InvalidKeyException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import jav

随机推荐