AES和Base64加密算法结合使用

    两种加密算法的结合使用是为了更加安全,使得真正的密码只用用户自己知道,并且外人河南破解。废话不多说,我这里直接写了AES加密算法和BASE64加密算法的工具类,可以直接调用

一. BASE64加密工具类

package com.AES;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.IOException;
/**
 * Created by ${ligh} on 2019/2/25 下午2:17
 */
public class BaseUtil {
    /**
     * 编码
     *
     * @param bstr
     * @return String
     */
    public static String encode(byte[] bstr) {
        return new BASE64Encoder().encode(bstr);
    }
    /**
     * 解码
     *
     * @param str
     * @return string
     */
    public static byte[] decode(String str) {
        byte[] bt = null;
        try {
            BASE64Decoder decoder = new BASE64Decoder();
            bt = decoder.decodeBuffer(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bt;
    }
}

二. AES加密算法工具类

package com.AES;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.MessageDigest;
/**
 * Created by ${ligh} on 2019/02/27 下午4:01
 */
public class AESUtil {

    /**
     * 預設的Initialization Vector,為16 Bits的0
     */
    private static final IvParameterSpec DEFAULT_IV = new IvParameterSpec(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
    /**
     * 加密演算法使用AES
     */
    private static final String ALGORITHM = "AES";
    /**
     * AES使用CBC模式與PKCS5Padding
     */
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";

    /**
     * 取得AES加解密的密鑰
     */
    private Key key;
    /**
     * AES CBC模式使用的Initialization Vector
     */
    private IvParameterSpec iv;
    /**
     * Cipher 物件
     */
    private Cipher cipher;

    /**
     * 建構子,使用128 Bits的AES密鑰(計算任意長度密鑰的MD5)和預設IV
     *
     * @param key 傳入任意長度的AES密鑰
     */
    public AESUtil(final String key) {
        this(key, 128);
    }

    /**
     * 建構子,使用128 Bits或是256 Bits的AES密鑰(計算任意長度密鑰的MD5或是SHA256)和預設IV
     *
     * @param key 傳入任意長度的AES密鑰
     * @param bit 傳入AES密鑰長度,數值可以是128、256 (Bits)
     */
    public AESUtil(final String key, final int bit) {
        this(key, bit, null);
    }

    /**
     * 建構子,使用128 Bits或是256 Bits的AES密鑰(計算任意長度密鑰的MD5或是SHA256),用MD5計算IV值
     *
     * @param key 傳入任意長度的AES密鑰
     * @param bit 傳入AES密鑰長度,數值可以是128、256 (Bits)
     * @param iv 傳入任意長度的IV字串
     */
    public AESUtil(final String key, final int bit, final String iv) {
        if (bit == 256) {
            this.key = new SecretKeySpec(getHash("SHA-256", key), ALGORITHM);
        } else {
            this.key = new SecretKeySpec(getHash("MD5", key), ALGORITHM);
        }
        if (iv != null) {
            this.iv = new IvParameterSpec(getHash("MD5", iv));
        } else {
            this.iv = DEFAULT_IV;
        }

        init();
    }

    /**
     * 取得字串的雜湊值
     *
     * @param algorithm 傳入雜驟演算法
     * @param text 傳入要雜湊的字串
     * @return 傳回雜湊後資料內容
     */
    private static byte[] getHash(final String algorithm, final String text) {
        try {
            return getHash(algorithm, text.getBytes("UTF-8"));
        } catch (final Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 取得資料的雜湊值
     *
     * @param algorithm 傳入雜驟演算法
     * @param data 傳入要雜湊的資料
     * @return 傳回雜湊後資料內容
     */
    private static byte[] getHash(final String algorithm, final byte[] data) {
        try {
            final MessageDigest digest = MessageDigest.getInstance(algorithm);
            digest.update(data);
            return digest.digest();
        } catch (final Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 初始化
     */
    private void init() {
        try {
            cipher = Cipher.getInstance(TRANSFORMATION);
        } catch (final Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 加密文字
     *
     * @param str 傳入要加密的文字
     * @return 傳回加密後的文字
     */
    public String encrypt(final String str) {
        try {
            return encrypt(str.getBytes("UTF-8"));
        } catch (final Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 加密資料
     *
     * @param data 傳入要加密的資料
     * @return 傳回加密後的資料
     */
    public String encrypt(final byte[] data) {
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key, iv);
            final byte[] encryptData = cipher.doFinal(data);
            return BaseUtil.encode(encryptData);
        } catch (final Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 解密文字
     *
     * @param str 傳入要解密的文字
     * @return 傳回解密後的文字
     */
    public String decrypt(final String str) {
        try {
            return decrypt(BaseUtil.decode(str));
        } catch (final Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 解密文字
     *
     * @param data 傳入要解密的資料
     * @return 傳回解密後的文字
     */
    public String decrypt(final byte[] data) {
        try {
            cipher.init(Cipher.DECRYPT_MODE, key, iv);
            final byte[] decryptData = cipher.doFinal(data);
            return new String(decryptData, "UTF-8");
        } catch (final Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }
}

三. 创建测试

package com.AES;
/**
 * Created by ${ligh} on 2019/2/27 下午4:46
 */
public class TestAesBase {
    public static void main(String[] args) {
        String key = "ligh";
        String phone = "123456";
        System.out.println("加密前的字符串: "+phone);
        AESUtil aesUtil = new AESUtil(key);
        String encrypt = aesUtil.encrypt(phone);
        System.out.println("加密后的字符串: "+ encrypt);

        String decrypt = aesUtil.decrypt(encrypt);
        System.out.println("解密之后的字符串: "+decrypt);
    }
}

显示结果:
在这里插入图片描述

四. 总结

注意:
    构造方法中传入的参数一定要在加密和解密前统一,不然会出现解密失败的现象

猜你喜欢

转载自blog.csdn.net/ligh_sqh/article/details/87979728