java AES加密、解密(兼容windows和linux)

 

java AES加密、解密

CreationTime--2018年7月14日10點06分

Author:Marydon

1.準備工做

  updateTime--2018年8月10日15點28分html

  updateTime--2018年10月24日10點46分java

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.log4j.Logger;
import dzkjk.web.tools.ByteUtils;
 
/**
 * AES加密算法工具類
 * @explain 可逆算法:加密、解密
 * AES/ECB/PKCS5Padding
 * @author Marydon
 * @creationTime 2018年7月7日下午2:17:43
 * @version 3.0
 * @since 2.0
 * @email marydon20170307@163.com
 */
public class AESUtils {
 
    private static Logger log = Logger.getLogger(AESUtils.class);
    // 定義字符集
    private static final String ENCODING = "UTF-8";
 
    /**
     * 根據提供的密鑰生成AES專用密鑰
     * @explain
     * @param password
     *            能夠是中文、英文、16進制字符串
     * @return AES密鑰
     * @throws Exception
     */
    public static byte[] generateKey(String password) throws Exception {
        byte[] keyByteArray = null;
        // 建立AES的Key生產者
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        // 利用用戶密碼做爲隨機數初始化
        // 128位的key生產者
        // 加密不要緊,SecureRandom是生成安全隨機數序列,password.getBytes()是種子,只要種子相同,序列就同樣,因此解密只要有password就行
		/*
		 * 只適用windows
		 * kgen.init(128, new SecureRandom(password.getBytes(ENCODING)));
		 */
        
        // 指定強隨機數的生成方式
        // 兼容linux
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        random.setSeed(password.getBytes(ENCODING));
        kgen.init(128, random);// 只能是128位
         
        // 根據用戶密碼,生成一個密鑰
        SecretKey secretKey = kgen.generateKey();
        // 返回基本編碼格式的密鑰,若是此密鑰不支持編碼,則返回null。
        keyByteArray = secretKey.getEncoded();
        return keyByteArray;
    }
}    

2.AES加密

/**
 * AES加密字符串
 * @param content
 *            須要被加密的字符串
 * @param password
 *            加密須要的密碼
 * @return 16進制的密文(密文的長度隨着待加密字符串的長度變化而變化,至少32位)
 */
public static String encrypt(String content, String password) {
    String cipherHexString = "";// 返回字符串
    try {
        // 轉換爲AES專用密鑰
    	byte[] keyBytes = generateKey(password);
    	
    	SecretKeySpec sks = new SecretKeySpec(keyBytes, "AES");
    	// 將待加密字符串轉二進制
        byte[] clearTextBytes = content.getBytes(ENCODING);
        // 建立密碼器
        Cipher cipher = Cipher.getInstance("AES");
        // 初始化爲加密模式的密碼器
        cipher.init(Cipher.ENCRYPT_MODE, sks);
        // 加密結果
        byte[] cipherTextBytes = cipher.doFinal(clearTextBytes);
        // byte[]-->hexString
        cipherHexString = ByteUtils.toHexString(cipherTextBytes);
    } catch (Exception e) {
        e.printStackTrace();
        log.error("AES加密失敗:" + e.getMessage());
    }
    log.info("AES加密結果:" + cipherHexString);
    return cipherHexString;
}

3.AES解密

/**
 * 解密AES加密過的字符串
 * @param content
 *            16進制密文
 * @param password
 *            加密時的密碼
 * @return 明文
 */
public static String decrypt(String hexString, String password) {
    String clearText = "";
    try {
    	// 轉換爲AES專用密鑰
    	byte[] keyBytes = generateKey(password);
    	
    	SecretKeySpec sks = new SecretKeySpec(keyBytes, "AES");
        // 建立密碼器
        Cipher cipher = Cipher.getInstance("AES");
        // 初始化爲解密模式的密碼器
        cipher.init(Cipher.DECRYPT_MODE, sks);
        // hexString-->byte[]
        // 將16進制密文轉換成二進制
        byte[] cipherTextBytes = ByteUtils.fromHexString(hexString);
        // 解密結果
        byte[] clearTextBytes = cipher.doFinal(cipherTextBytes);
        // byte[]-->String
        clearText = new String(clearTextBytes, ENCODING);
    } catch (Exception e) {
        e.printStackTrace();
        log.error("AES解密失敗:" + e.getMessage());
    }
    log.info("AES解密結果:" + clearText);
    return clearText;
}

4.測試

public static void main(String[] args) {
    String json = "{\"name\":\"Marydon\",\"website\":\"http://www.cnblogs.com/Marydon20170307\"}";
    String password = "測試";
    // 加密
    String encrypt = encrypt(json, password);
    // 解密
    String decrypt = decrypt(encrypt, password);
}

 

相關文章
相關標籤/搜索