JAVA AES CBC 加密 解密
Posted runliuv
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA AES CBC 加密 解密相关的知识,希望对你有一定的参考价值。
AES 256 , KEY 的长度为 32字节(32*8=256bit).
AES 128 , KEY 的长度为 16字节(16*8=128bit)
CBC 模式需要IV, IV的值是固定写死,还是当参数传入,自己看情况。IV的长度没研究,这里用的是16字符。
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 加密 解密的主要内容,如果未能解决你的问题,请参考以下文章
QT:AES-256-CBC 根据 PHP 代码在 C++ 中加密/解密