1. 程式人生 > >java 使用AES對資料進行加密和解密

java 使用AES對資料進行加密和解密

最近做的聊天功能,李老闆希望對聊天的資料進行加密,然後存入資料庫,首先想到的便是AES加密的方式,以前也用過幾次,這次正好記錄下來:

MD5加密是不可逆的,可以對使用者的密碼加密;
AES加密是可逆的,可以對資料庫的資料進行加密,因為使用者查詢資料時,要返回明文,適合。

public class AESUtil {
	private static String key= "123456";
	/**
	 * 加密
	 * @param content待加密內容
	 * @param key 加密的金鑰
	 * @return
	 */
	public static String encrypt
(String content, String key) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES");//構造金鑰生成器,指定為AES演算法,不區分大小寫 kgen.init(128, new SecureRandom(key.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec secretKeySpec = new
SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES"); byte[] byteContent = content.getBytes("utf-8"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);//ENCRYPT_MODE指加密操作 byte[] byteRresult = cipher.doFinal(byteContent); StringBuffer sb = new StringBuffer(); for
(int i = 0; i < byteRresult.length; i++) { String hex = Integer.toHexString(byteRresult[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } sb.append(hex.toUpperCase()); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null; } /** * 解密 * @param content 待解密內容 * @param key 解密的金鑰 * @return */ public static String decrypt(String content, String key) { if (content.length() < 1) return null; byte[] byteRresult = new byte[content.length() / 2]; for (int i = 0; i < content.length() / 2; i++) { int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16); int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2),16); byteRresult[i] = (byte) (high * 16 + low); } try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); secureRandom.setSeed(key.getBytes()); kgen.init(128, secureRandom); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);//Decrypt_mode指解密操作 byte[] result = cipher.doFinal(byteRresult); return new String(result,"utf-8");//不加utf-8,中文時會亂碼 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); }catch (Exception e) { e.printStackTrace(); } return null; } //過載的方法,使用預設金鑰 public static String decrypt(String content) { return decrypt(content, key); } public static String encrypt(String content) { return encrypt(content, key); }

遇到的問題:
1.javax.crypto.BadPaddingException: Given final block not properly padded
加密的金鑰和解密的金鑰不一致丟擲該異常。
引用Stack Overflow:
If you try to decrypt PKCS5-padded data with the wrong key, and then unpad it (which is done by the Cipher class automatically), you most likely will get the BadPaddingException (with probably of slightly less than 255/256, around 99.61%), because the padding has a special structure which is validated during unpad and very few keys would produce a valid padding.
So, if you get this exception, catch it and treat it as “wrong key”.

2.含中文的資料加密後,進行解密會亂碼
在解密的方法位元組陣列轉字串方法中,指明編碼方式為UTF-8