Java web

AES加密以及工具类

2020-06-30  本文已影响0人  salt丶

对称加密:

对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。

AES加密:

高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥,具有以下几个特点:
1、最常用的对称加密算法
2、密钥建立时间短、灵敏性好、内存需求低
3、实际使用中,使用工作模式为CTR(最好用BC去实现),此工作模式需要引入IV参数(16位的字节数组)
4、密钥长度128/192/256,其中192与256需要配置无政策限制权限文件(JDK6)
5、填充模式最常用的两种PKCS5Padding和PKCS7Padding,其中后者只有BC独有。
6、加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合

简叙和非对称加密场景的差异对称加密:适合经常发送数据的场合非对称加密:加密和解密用的密钥是不同的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。

非对称加密:加密和解密用的密钥是不同的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。

具体的加密流程如下图:


image

生成AES秘钥工具类:

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

public void make() throws NoSuchAlgorithmException {
        BASE64Encoder base64Encoder = new BASE64Encoder();

        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        System.out.println("AES: " + base64Encoder.encode(raw).replaceAll("\r|\n", ""));

    }

AES加解密工具类:

import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;


public class EncryptUtil {

    public static final String key = "秘钥";

    /**
     * 密钥算法
     */
    public static final String KEY_ALGORITHM = "AES";

    /**
     * 加密/解密算法 / 工作模式 / 填充方式
     */
    public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    /**
     * 转换密钥
     *
     * @param key 二进制密钥
     * @return Key 密钥
     * @throws Exception
     */
    private static Key toKey(byte[] key) throws Exception {

        // 实例化AES密钥材料
        SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);

        return secretKey;
    }
    /**
     * 解密
     *
     * @param data 待解密数据
     * @param key 密钥
     * @return byte[] 解密数据
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {

        // 还原密钥
        Key k = toKey(key);

        /*
         * 实例化
         * 使用PKCS7Padding填充方式,按如下方式实现
         * Cipher.getInstance(CIPHER_ALGORITHM, "BC");
         */
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        // 初始化,设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, k);

        // 执行操作
        return cipher.doFinal(data);
    }

    /**
     * 加密
     *
     * @param data 待加密数据
     * @param key 密钥
     * @return byte[] 加密数据
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {

        // 还原密钥
        Key k = toKey(key);

        /*
         * 实例化
         * 使用PKCS7Padding填充方式,按如下方式实现
         * Cipher.getInstance(CIPHER_ALGORITHM, "BC");
         */
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        // 初始化,设置为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, k);

        // 执行操作
        return cipher.doFinal(data);
    }

    public static String encrypt(String keyStr,String data,String charset)throws Exception{
        byte[] keyBytes = Base64.decodeBase64(keyStr.getBytes(charset));
        byte[]dataBytes=data.getBytes(charset);
        byte[]encryptedBytes=encrypt(dataBytes,keyBytes);
        return  new String(Base64.encodeBase64(encryptedBytes), charset);

    }
    public static String decrypt(String keyStr,String encryptedData,String charset)throws Exception{
        BASE64Encoder base64Encoder = new BASE64Encoder();
        byte[] keyBytes = Base64.decodeBase64(keyStr.getBytes(charset));
        byte[] encryptedDataBytes = Base64.decodeBase64(encryptedData.getBytes(charset));
        byte[] dataBytes = decrypt(encryptedDataBytes, keyBytes);
        return  new String(dataBytes, charset);
    }

}

验证:

 public static void main(String[] args) throws Exception {
        Map inMap = RMap.asMap("phone","14700000000");
        String s = JSON.toJSONString(inMap);
        String aesData = EncryptUtil.encrypt(EncryptUtil.key,s,"utf-8");

        System.out.println("data 加密后参数:" + aesData);
        String decryptedData = EncryptUtil.decrypt(EncryptUtil.key,aesData,"utf-8");
        System.out.println("data 解密后的参数:" + decryptedData);
    }

//输出结果:
data 加密后参数:knlYATMUWUBWbliaF+hIMFVwy331bDyIRQPGsbHU4VI=
data 解密后的参数:{"phone":"14700000000"}
上一篇下一篇

猜你喜欢

热点阅读