java封裝AES加密算法


在實際coding中會常常遇到往數據庫存入密碼時加密。URL傳參時的加密。由此簡單封裝了下java中的AES加密算法。

0、import類

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.axis.encoding.Base64; //非必須

1、加密接口

    /** * 加密 * @param content 待加密內容 * @param password 加密密鑰 * @return */
    public static byte[] encrypt(String content, String password) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(password.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            byte[] byteContent = content.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] result = cipher.doFinal(byteContent);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

2、解密接口

    /**解密 * @param content 待解密內容 * @param password 解密密鑰 * @return */
    public static byte[] decrypt(byte[] content, String password) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(password.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

3、編解碼函數(非必須)

    //編碼函數
    public static String encode(String content, String key) throws Exception {
        byte[] encrypt = encrypt(content, key);
        return Base64.encode(encrypt);
    }
    //解碼函數
    public static String decode(String encode, String key) throws Exception {
        byte[] encrypt = Base64.decode(encode);
        byte[] content = decrypt(encrypt, key);
        return new String(content);
    }

4、測試

    //0-正常使用
    public static void main(String[] args) throws Exception{
        String content = "holybin";
        String password = "12345678";

        System.out.println("加密前1:" + content);
        byte[] encryptResult1 = encrypt(content, password); //普通加密
        byte[] decryptResult1 = decrypt(encryptResult1,password);   //普通解密
        System.out.println("解密后1:" + new String(decryptResult1));

        System.out.println("\n加密前2:" + content);
        String encryptResult2 = encode(content, password);  //先編碼再加密
        System.out.println("加密后2:" + encryptResult2);
        String decryptResult2 = decode(encryptResult2, password);   //先解碼再解密
        System.out.println("解密后2:" + decryptResult2);
    }

結果例如以下:
這里寫圖片描寫敘述

5、問題與思考

(1)普通加密后將得到的byte數組直接轉化為字符串用於輸出,或者普通解密時從字符串轉換為byte數組用於傳參會發生什么?

    //1-先測試加密
    public static void main(String[] args) throws Exception{
        String content = "holybin";
        String password = "12345678";

        System.out.println("加密前1:" + content);
        byte[] encryptResult1 = encrypt(content, password); //普通加密
        System.out.println("加密后1:" + encryptResult1);
        System.out.println("加密后1:" + new String(encryptResult1));
        byte[] decryptResult1 = decrypt(encryptResult1,password);   //普通解密
        System.out.println("解密后1:" + new String(decryptResult1));
    }

結果1:
這里寫圖片描寫敘述
這里將加密后的byte數組直接轉化成String輸出。出現亂碼。

    //2-再測試解密
    public static void main(String[] args) throws Exception{
        String content = "holybin";
        String password = "12345678";

        System.out.println("加密前1:" + content);
        byte[] encryptResult1 = encrypt(content, password); //普通加密
        String strEncryptResult1 = new String(encryptResult1,"UTF-8");
        //System.out.println("加密后1:" + strEncryptResult1);
        byte[] decryptResult1 = decrypt(strEncryptResult1.getBytes("UTF-8"),password);  //普通解密
        System.out.println("解密后1:" + new String(decryptResult1));
    }

結果2:
這里從加密后的String提取bytes數組用於解密,出現報錯
這里寫圖片描寫敘述

原因:主要是由於加密后的byte數組是不能強制轉換成字符串的,加密過的字符串也不能直接提取bytes數組用於解密,解決方法有兩個:一是像上面測試的樣例一樣先加密再編碼,或先解碼再解密(參考:4、測試)。二是採用十六進制和二進制的相互轉化函數(參考:以下的第(2)點)。

(2)十六進制和二進制相互轉化函數

    // 二進制轉十六進制
    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 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;
    }

使用演示樣例:

    // 3-測試轉化函數
    public static void main(String[] args) throws Exception {
        String content = "holybin";
        String password = "12345678";
        //加密
        System.out.println("加密前1:" + content);
        byte[] encryptResult = encrypt(content, password);  // 普通加密
        String strEncryptResult = parseByte2HexStr(encryptResult);
        System.out.println("加密后1:" + strEncryptResult);
        //解密
        byte[] byteDecryptResult = parseHexStr2Byte(strEncryptResult);
        byte[] decryptResult = decrypt(byteDecryptResult, password);    // 普通解密
        System.out.println("解密后1:" + new String(decryptResult));
    }

結果:
這里寫圖片描寫敘述

測試代碼:EncrptDecrypt.java


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM