1. 程式人生 > >JAVA AES CBC 加密 解密

JAVA AES CBC 加密 解密

crypto byte[] decrypt amp code chan 導致 cati instance

AES 256 , KEY 的長度為 32字節(32*8=256bit).

AES 128 , KEY 的長度為 16字節(16*8=128bit)

CBC 模式需要IV, IV的值是固定寫死,還是當參數傳入,自己看情況。

java PKCS5Padding 對應 C#.NET 的 PKCS7 。

明文,KEY和IV 三者 string 轉 byte[] 時要統一編碼,如UTF-8。

加密後 cipher.doFinal() 得到密文byte[] ,是直接轉string,還是轉為base64編碼的string ,要統一。

AesCbc:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 
*/ package javaapplication1; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; /** * * @author jk */ public class AesCbc { private static final String IV_STRING = "abcdefghABCDEFGH"; private static final String charset = "UTF-8";
// AES 266 = KEY 長度是32個字符 = (32*8=266) public static String encrypt(String content, String key) { try { byte[] contentBytes = content.getBytes(charset); byte[] keyBytes = key.getBytes(charset); byte[] encryptedBytes = aesEncryptBytes(contentBytes, keyBytes); return Base64Utils.encode(encryptedBytes); } catch (Exception e) { e.printStackTrace(); } return null; } public static byte[] aesEncryptBytes(byte[] contentBytes, byte[] keyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { return cipherOperation(contentBytes, keyBytes, Cipher.ENCRYPT_MODE); } private static byte[] cipherOperation(byte[] contentBytes, byte[] keyBytes, int mode) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { //cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(java.util.Base64.Decoder.decode(IV. SecretKeySpec keySpec=new SecretKeySpec(keyBytes,"AES"); Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] initParam=IV_STRING.getBytes(charset); IvParameterSpec ivParameterSpec=new IvParameterSpec(initParam); // SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES"); // byte[] initParam = IV_STRING.getBytes(charset); // IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); // Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(mode, keySpec, ivParameterSpec); return cipher.doFinal(contentBytes); } public static String decrypt(String content, String key) { try { byte[] encryptedBytes = Base64Utils.decode(content); byte[] keyBytes = key.getBytes(charset); byte[] decryptedBytes = aesDecryptBytes(encryptedBytes, keyBytes); return new String(decryptedBytes, charset); }catch (Exception e){ e.printStackTrace(); } return null; } public static byte[] aesDecryptBytes(byte[] contentBytes, byte[] keyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { return cipherOperation(contentBytes, keyBytes, Cipher.DECRYPT_MODE); } }

Base64Utils:

package javaapplication1;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.codec.binary.Base64;

/**
 *  */
/**
 * <p>
 * BASE64編碼解碼工具包
 * </p>
 * <p>
 * 依賴javabase64-1.3.1.jar
 * </p>
 *
 * @author IceWee
 * @date 2012-5-19
 * @version 1.0
 */
public class Base64Utils {

    /**
     *      */
    /**
     * 文件讀取緩沖區大小
     */
    private static final int CACHE_SIZE = 1024;

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

    /**
     *      */
    /**
     * <p>
     * BASE64字符串解碼為二進制數據
     * </p>
     *
     * @param base64
     * @return
     * @throws Exception
     */
    public static byte[] decode(String str) throws Exception {
        Base64 _base64 = new Base64();
        return _base64.decodeBase64(str.getBytes(_charset));
    }

    /**
     *      */
    /**
     * <p>
     * 二進制數據編碼為BASE64字符串
     * </p>
     *
     * @param bytes
     * @return
     * @throws Exception
     */
    public static String encode(byte[] bytes) throws Exception {
        Base64 _base64 = new Base64();
        return new String(_base64.encodeBase64Chunked(bytes));
    }

    /**
     *      */
    /**
     * <p>
     * 將文件編碼為BASE64字符串
     * </p>
     * <p>
     * 大文件慎用,可能會導致內存溢出
     * </p>
     *
     * @param filePath 文件絕對路徑
     * @return
     * @throws Exception
     */
    public static String encodeFile(String filePath) throws Exception {
        byte[] bytes = fileToByte(filePath);
        return encode(bytes);
    }

    /**
     *      */
    /**
     * <p>
     * BASE64字符串轉回文件
     * </p>
     *
     * @param filePath 文件絕對路徑
     * @param base64 編碼字符串
     * @throws Exception
     */
    public static void decodeToFile(String filePath, String base64) throws Exception {
        byte[] bytes = decode(base64);
        byteArrayToFile(bytes, filePath);
    }

    /**
     *      */
    /**
     * <p>
     * 文件轉換為二進制數組
     * </p>
     *
     * @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;
    }

    /**
     *      */
    /**
     * <p>
     * 二進制數據寫文件
     * </p>
     *
     * @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();
    }

}

base 64 編碼引用了 org.apache.commons.codec.binary.Base64,可以從網上下載。

測試代碼 main:

static void TestAesCbc() {
        String cc = "中華人民共和國~!@#¥%……&*()——+12345678ABC中華人民共和國~!@#¥%……&*()——+12345678ABC中華人民共和國~!@#¥%……&*()——+12345678ABC中華人民共和國~!@#¥%……&*()——+12345678ABC";
        System.out.println("明文:\r\n" + cc);

        System.out.println("AES 256 -------:\r\n");
        String aesKey = "12345678901234567890123456789012";
        String aa = AesCbc.encrypt(cc, aesKey);
        System.out.println("密文:\r\n" + aa);
        String dd = AesCbc.decrypt(aa, aesKey);
        System.out.println("解密後明文:\r\n" + dd);

        System.out.println("AES 128 -------:\r\n");
        String aesKey2 = "1234567890123456";
        aa = AesCbc.encrypt(cc, aesKey2);
        System.out.println("密文:\r\n" + aa);
        dd = AesCbc.decrypt(aa, aesKey2);
        System.out.println("解密後明文:\r\n" + dd);
    }

end

JAVA AES CBC 加密 解密