JAVA AES CBC 加密 解密
阿新 • • 發佈:2019-03-30
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 加密 解密