zoukankan      html  css  js  c++  java
  • Java-AESUtil

    在线版 http://tool.chacuo.net/cryptaes

    要使用 AES/CBC/PKCS7Padding 模式需要添加依赖

    <!--AES/CBC/PKCS7Padding-->
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk16</artifactId>
        <version>1.46</version>
    </dependency>

    AES 工具类

    // 加密算法
    private static final String ENCRY_ALGORITHM = "AES";
    // 加密算法/加密模式/填充类型
    private static final String CIPHER_MODE = "AES/CBC/PKCS7Padding";
    // 设置iv偏移量,ECB加密模式不需要设置 iv 偏移量
    private static final String IV = "0000000000000000";
    // 设置加密字符集
    private static final String CHARACTER = "UTF-8";
    // 加密密码长度。默认 16 byte * 8 = 128 bit
    private static final int PWD_SIZE = 16;
    
    static {
        // 添加 AES/CBC/PKCS7Padding 支持
        Security.addProvider(new BouncyCastleProvider());
    }
    
    public static void main(String[] args) {
        String str = "NiHao";
        byte[] encryptAES = encryptAES(str, "1234567899874563");
        byte[] decryptAES = decryptAES(encryptAES, "1234567899874563");
        System.out.println(new String(decryptAES));
    }
    
    /**
     * 密码长度不足补"0"
     */
    private static byte[] pwdHandler(String password) throws UnsupportedEncodingException {
        byte[] data = null;
        if (password == null) {
            password = "";
        }
        StringBuffer sb = new StringBuffer(PWD_SIZE);
        sb.append(password);
        while (sb.length() < PWD_SIZE) {
            sb.append("0");
        }
        if (sb.length() > PWD_SIZE) {
            sb.setLength(PWD_SIZE);
        }
        data = sb.toString().getBytes(CHARACTER);
        return data;
    }
    
    /**
     * AES 加密
     *
     * @param cleartext 明文
     * @param key       密钥
     * @return
     */
    public static byte[] encryptAES(String cleartext, String key) {
        try {
            // 获取加密密钥
            SecretKeySpec keySpec = new SecretKeySpec(pwdHandler(key), ENCRY_ALGORITHM);
            // 获取Cipher实例
            Cipher cipher = Cipher.getInstance(CIPHER_MODE);
    
            // 查看数据块位数 默认为16(byte) * 8 =128 bit
            // System.out.println("数据块位数(byte):" + cipher.getBlockSize());
    
            // 初始化Cipher实例。设置执行模式以及加密密钥
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(IV.getBytes(CHARACTER)));
            // 执行
            byte[] cipherTextBytes = cipher.doFinal(cleartext.getBytes(CHARACTER));
            return cipherTextBytes;
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * AES 解密
     *
     * @param ciphertext 密文
     * @param key        密钥
     * @return
     */
    public static byte[] decryptAES(byte[] ciphertext, String key) {
        try {
            // 获取解密密钥
            SecretKeySpec keySpec = new SecretKeySpec(pwdHandler(key), ENCRY_ALGORITHM);
            // 获取Cipher实例
            Cipher cipher = Cipher.getInstance(CIPHER_MODE);
    
            // 查看数据块位数 默认为16(byte) * 8 =128 bit
            // System.out.println("数据块位数(byte):" + cipher.getBlockSize());
    
            // 初始化Cipher实例。设置执行模式以及加密密钥
            cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(IV.getBytes(CHARACTER)));
            // 执行
            byte[] clearTextBytes = cipher.doFinal(ciphertext);
            return clearTextBytes;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 解密错误 返回 null
        return null;
    }

    加密后通常配合 Base64 进行编码

    public static void main(String[] args) {
        String str = "NiHao";
        byte[] encryptAES = encryptAES(str, "1234567899874563");
        String encryptBase64 = encryptBase64(encryptAES);
    
        byte[] decryptBase64 = decryptBase64(encryptBase64);
        byte[] decryptAES = decryptAES(decryptBase64, "1234567899874563");
        System.out.println(new String(decryptAES));
    }
    
    /**
     * BASE64 加密
     *
     * @param cleartext 明文
     * @return 密文
     */
    public static String encryptBase64(byte[] cleartext) {
        BASE64Encoder base64Encoder = new BASE64Encoder();
        String cipherText = base64Encoder.encode(cleartext);
        return cipherText;
    }
    
    /**
     * BASE64 解密
     *
     * @param cipherText 密文
     * @return 明文
     */
    public static byte[] decryptBase64(String cipherText) {
        try {
            BASE64Decoder base64Decoder = new BASE64Decoder();
            byte[] cipherTextBytes = base64Decoder.decodeBuffer(cipherText);
            return cipherTextBytes;
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 解密错误返回 null
        return null;
    }

    也可以使用 16 进制编码

    public static void main(String[] args) {
        String str = "NiHao";
        byte[] encryptAES = encryptAES(str, "1234567899874563");
        String encryptHex = encryptHex(encryptAES);
    
        byte[] decryptHex = decryptHex(encryptHex);
        byte[] decryptAES = decryptAES(decryptHex, "1234567899874563");
        System.out.println(new String(decryptAES));
    }
    
    /**
     * HEX 加密(字节数组转成16进制字符串)
     *
     * @param clearText 明文
     * @return 密文
     */
    public static String encryptHex(byte[] clearText) {
        // 一个字节的数,
        StringBuffer sb = new StringBuffer(clearText.length * 2);
        String tmp = "";
        for (int n = 0; n < clearText.length; n++) {
            // 整数转成十六进制表示
            tmp = (java.lang.Integer.toHexString(clearText[n] & 0XFF));
            if (tmp.length() == 1) {
                sb.append("0");
            }
            sb.append(tmp);
        }
        // 转成大写
        String cipherText = sb.toString().toUpperCase();
        return cipherText;
    }
    
    /**
     * HEX 解密(16进制字符串转换成字节数组)
     *
     * @param cipherText 密文
     * @return 明文
     */
    public static byte[] decryptHex(String cipherText) {
        if (cipherText == null || cipherText.length() < 2) {
            return new byte[0];
        }
        cipherText = cipherText.toLowerCase();
        int l = cipherText.length() / 2;
        byte[] cipherTextBytes = new byte[l];
        for (int i = 0; i < l; ++i) {
            String tmp = cipherText.substring(2 * i, 2 * i + 2);
            cipherTextBytes[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);
        }
        return cipherTextBytes;
    }

    编码后若作为 URL 参数还需进行 URI 转换

    public static String encodeURIComponent(String s) {
        String result = null;
        try {
            result = URLEncoder.encode(s, CHARACTER)
                    .replaceAll("\+", "%20")
                    .replaceAll("\%21", "!")
                    .replaceAll("\%27", "'")
                    .replaceAll("\%28", "(")
                    .replaceAll("\%29", ")")
                    .replaceAll("\%7E", "~");
        } catch (UnsupportedEncodingException e) {
            result = s;
        }
        return result;
    }
    
    public static String decodeURIComponent(String s) {
        if (s == null) {
            return null;
        }
        String result = null;
        try {
            result = URLDecoder.decode(s, CHARACTER);
        } catch (UnsupportedEncodingException e) {
            result = s;
        }
        return result;
    }

    https://segmentfault.com/a/1190000015943620

    https://blog.csdn.net/wangweiren_get/article/details/82585629

  • 相关阅读:
    如何写一个bat文件,让他去执行某一个地方的bat文件
    服务器加电自动开机模式设置
    第三章 线程状态
    第二章 线程安全
    第一章 线程
    多线程入门
    异常
    SSO系统介绍
    解决:Nginx访问静态页面出现中文乱码
    错误处理:java.lang.NoClassDefFoundError: javax/jms/JMSContext
  • 原文地址:https://www.cnblogs.com/jhxxb/p/11171380.html
Copyright © 2011-2022 走看看