AESおよびRSA暗号化と復号化を使用してJava

  • 最初の理解では、暗号化積まれているもの、非対称暗号化は何ですか?

  対称暗号化:暗号化と復号鍵は、AESと同じ、非常に高速な暗号化、あります

  非対称暗号化:暗号化と復号鍵が異なっている、遅く、RSAなど

 

  • (この研究で使用される)コードを見てください 

  その依存関係:

     <依存性> 
          <のgroupId> org.bouncycastle </のgroupId> 
          <たartifactId> bcprov-jdk15on </たartifactId> 
          <バージョン> 1.58 </バージョン> 
      </依存>

 

  

       1、RSAツール:

パッケージcn.wangtao.utils。

輸入org.bouncycastle.jce.provider.BouncyCastleProvider。
輸入org.slf4j.Logger。
輸入org.slf4j.LoggerFactory; 

輸入javax.crypto.Cipher; 
輸入java.io.ByteArrayOutputStreamを。
輸入java.io.FileOutputStreamは、
インポートにjava.io.IOException; 
輸入java.io.ObjectOutputStreamの。
インポートjava.security *。; 
輸入java.security.interfaces.RSAPrivateKey。
輸入java.security.interfaces.RSAPublicKey。

/ ** 
 * @ClassName RSAUtils 
 * @Auth桃子
 * @Date 2019年6月25日15:15 
 * @Version 1.0 
 * @description 
 ** / 
パブリッククラスRSAUtils {

    プライベート静的最後の文字列RSA = "RSA "; // 暗号化
プライベート静的ロガーロガー=最終LoggerFactory.getLogger(RSAUtils.class); //キー取得 のpublic staticキーペアのgetKey()が例外{スロー 試し{ するKeyPairGenerator KeyPairGeneratorのがするKeyPairGeneratorを=を。 getInstance(RSA、新しい新しいBouncyCastleProvider()); keyPairGenerator.initialize(2048); //初期化キーの長さ キーペア鍵ペア= keyPairGenerator.generateKeyPair(); //は、鍵ペア生成 リターン鍵ペアを; }キャッチ(例外E){ ロガー。エラー(「RSAキー取得異常」、E); スロー新しい新しい例外(「RSAキー取得異常」、E); } } //公開鍵暗号 encryptStr静的ストリングパブリック(公開のRSAPublicKey、文字列STR)は例外{スロー 試み{ ;暗号暗号= Cipher.getInstance(RSA、新しい新しいBouncyCastleProvider()) ; cipher.init(Cipher.ENCRYPT_MODE、公開) //暗号化 =バイト[]バイトGetBytesメソッド(str.getBytes()、暗号化); // 2は、16進数に変換 CommonUtils.parseByte2HexStr(バイト)=文字列結果、 戻り結果; }キャッチ(例外E){ logger.error(「RSA公開鍵を使用して異常な暗号化「)E、; スロー新しい新しい例外(」異常を使用してRSA公開鍵暗号」、E); } } //復号化するための秘密鍵 公共decryptStr静的な文字列(RSAPrivateKeyザ・のPrivateKey、文字列STRは)例外{スロー 試し{ ;暗号暗号= Cipher.getInstance(RSA、新しい新BouncyCastleProvider()) cipher.init(Cipher.DECRYPT_MODE、のPrivateKeyを); //この暗号の鍵を使って初期化オブジェクト //進数をバイナリに変換される バイト[]バイト= CommonUtils.parseHexStr2Byte(STR); //復号 バイト[] BS = GetBytesメソッド(バイト、暗号化); 文字列のコンテンツは=新しい新しい文字列(BS、「UTF-8。 「); コンテンツを返す; }キャッチ(例外E){ logger.error(」異常解読するためにRSA秘密鍵を使用して「E); スロー新しい新しい例外(」「異常解読するためにRSA秘密鍵を使用して、E); } } //通过暗号获取字节数组 パブリック静的バイト[] GetBytesメソッド(バイト[]バイト、暗号暗号は){例外をスロー INTのblockSize = cipher.getBlockSize()。//返回块的大小 int型J = 0; ByteArrayOutputStreamたBAO =新しいByteArrayOutputStream(); 一方、(bytes.length - J *のblockSize> 0){//将二进制数据分块写入ByteArrayOutputStream中 であれば(bytes.length-J *のブロックサイズ>のblockSize){ baos.write(cipher.doFinal(バイト、j個の*ブロックサイズ、のblockSize))。 }他{ baos.write(cipher.doFinal(バイト、j個の*ブロックサイズ、bytes.length-J *のblockSize))。 } J ++; } baos.close()。 バイト[] BYTEARRAY = baos.toByteArray()。 リターンBYTEARRAY; } //はの秘密鍵にファイルを保存し ます。public voidのsaveRSAKey(ファイル名を文字列)例外{投げ たFileOutputStreamのFOS = NULL; ObjectOutputStreamのOOS = NULL; 試み{ キーペアキーペアのgetKey =(); FOS =新新のFileOutputStream(ファイル名); OOS =新しいObjectOutputStreamの(FOS); //の数列 oos.writeObject(キーペア); }キャッチ(例外E){ logger.error( "RSAの秘密鍵は、ファイル異常[{に保存}]"、ファイル名、 E)。 ;新しい例外(「異常上のファイルに保存されたRSA秘密鍵」、E)を投げる } {最後に oos.close(); !IF(OOS = NULL){ 試す{ }キャッチ(のIOExceptionのE1){ e1.printStackTrace()。 } } (!FOS = NULL)場合には{ {試みる )(fos.close。 }キャッチ(の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.utilsimport 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")){ //AES密文以空行结束,RSA使用Base64加密写入时,会换行 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"; //加密文件目录


}

 

 

  • AES的介绍

   详情请参考:https://blog.csdn.net/qq_28205153/article/details/55798628

  • RSA的介绍

        详情请参考:https://www.cnblogs.com/jiftle/p/7903762.html

おすすめ

転載: www.cnblogs.com/gdhzdbh/p/11101540.html