zoukankan      html  css  js  c++  java
  • 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,可以从网上下载。http://commons.apache.org/proper/commons-codec/download_codec.cgi

    --

    测试代码 main:

    static void TestAesCbc() {
            String cc = "中华人民共和国~!@#¥%……&*()——+12345678ABC中华人民共和国~!@#¥%……&*()——+12345678ABC中华人民共和国~!@#¥%……&*()——+12345678ABC中华人民共和国~!@#¥%……&*()——+12345678ABC";
            System.out.println("明文:
    " + cc);
    
            System.out.println("AES 256 -------:
    ");
            String aesKey = "12345678901234567890123456789012";
            String aa = AesCbc.encrypt(cc, aesKey);
            System.out.println("密文:
    " + aa);
            String dd = AesCbc.decrypt(aa, aesKey);
            System.out.println("解密后明文:
    " + dd);
    
            System.out.println("AES 128 -------:
    ");
            String aesKey2 = "1234567890123456";
            aa = AesCbc.encrypt(cc, aesKey2);
            System.out.println("密文:
    " + aa);
            dd = AesCbc.decrypt(aa, aesKey2);
            System.out.println("解密后明文:
    " + dd);
        }

    end

  • 相关阅读:
    MogoDb的使用及配置
    HttpClient中转上传文件
    springboot +Thymeleaf+UEditor整合记录
    Linux 下安装mysql
    Java开发微信公众号(五)---微信开发中如何获取access_token以及缓存access_token
    Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理
    Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装
    Java开发微信公众号(二)---开启开发者模式,接入微信公众平台开发
    Java开发微信公众号(一)---初识微信公众号以及环境搭建
    mybatis sql转义符号
  • 原文地址:https://www.cnblogs.com/runliuv/p/10625400.html
Copyright © 2011-2022 走看看