高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣爲全世界所使用。通過五年的甄選流程,高級加密標準由美國國家標準與技術研究院(NIST)於2001年11月26日發佈於FIPS PUB 197,並在2002年5月26日成爲有效的標準。2006年,高級加密標準已然成爲對稱密鑰加密中最流行的算法之一。java
1 package xin.dreaming.aes; 2 3 4 import javax.crypto.Cipher; 5 import javax.crypto.SecretKey; 6 import javax.crypto.spec.IvParameterSpec; 7 import javax.crypto.spec.SecretKeySpec; 8 9 import org.apache.commons.codec.binary.Base64; 10 import org.junit.Test; 11 public class AESUtils { 12 13 /** 14 * 生成隨機密鑰 15 * 16 * @param size 17 * 位數 18 * @return 19 */ 20 public static String generateRandomKey(int size) { 21 StringBuilder key = new StringBuilder(); 22 String chars = "0123456789ABCDEF"; 23 for (int i = 0; i < size; i++) { 24 int index = (int) (Math.random() * (chars.length() - 1)); 25 key.append(chars.charAt(index)); 26 } 27 return key.toString(); 28 } 29 30 /** 31 * AES加密 32 * 33 * @param plainBytes 34 * 明文字節數組 35 * @param keyBytes 36 * 對稱密鑰字節數組 37 * @param useBase64Code 38 * 是否使用Base64編碼 39 * @param charset 40 * 編碼格式 41 * @return byte[] 42 */ 43 public static byte[] encryptAES(byte[] plainBytes, byte[] keyBytes, boolean useBase64Code, String charset) throws Exception { 44 String cipherAlgorithm = "AES/CBC/PKCS5Padding"; 45 String keyAlgorithm = "AES"; 46 String IV = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 47 48 try { 49 Cipher cipher = Cipher.getInstance(cipherAlgorithm); 50 SecretKey secretKey = new SecretKeySpec(keyBytes, keyAlgorithm); 51 IvParameterSpec ivspec = new IvParameterSpec(IV.getBytes()); 52 53 cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec); 54 55 byte[] encryptedBlock = cipher.doFinal(plainBytes); 56 57 if (useBase64Code) { 58 return Base64.encodeBase64String(encryptedBlock).getBytes(charset); 59 } else { 60 return encryptedBlock; 61 } 62 } catch (Exception e) { 63 e.printStackTrace(); 64 throw new Exception("AES加密失敗"); 65 } 66 } 67 68 /** 69 * AES解密 70 * 71 * @param cryptedBytes 72 * 密文字節數組 73 * @param keyBytes 74 * 對稱密鑰字節數組 75 * @param useBase64Code 76 * 是否使用Base64編碼 77 * @param charset 78 * 編碼格式 79 * @return byte[] 80 */ 81 public static byte[] decryptAES(byte[] cryptedBytes, byte[] keyBytes, boolean useBase64Code, String charset) throws Exception { 82 String cipherAlgorithm = "AES/CBC/PKCS5Padding"; 83 String keyAlgorithm = "AES"; 84 String IV = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 85 86 byte[] data = null; 87 88 // 若是是Base64編碼的話,則要Base64解碼 89 if (useBase64Code) { 90 data = Base64.decodeBase64(new String(cryptedBytes, charset)); 91 } else { 92 data = cryptedBytes; 93 } 94 95 try { 96 Cipher cipher = Cipher.getInstance(cipherAlgorithm); 97 SecretKey secretKey = new SecretKeySpec(keyBytes, keyAlgorithm); 98 IvParameterSpec ivspec = new IvParameterSpec(IV.getBytes()); 99 100 cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec); 101 102 byte[] decryptedBlock = cipher.doFinal(data); 103 104 return decryptedBlock; 105 } catch (Exception e) { 106 e.printStackTrace(); 107 throw new Exception("AES解密失敗"); 108 } 109 } 110 111 /** 112 * BASE64加密 113 * 114 * @param key 115 * @return 116 * @throws Exception 117 */ 118 119 120 @Test 121 public void aesTest() throws Exception{ 122 String value ="DREAMING.XIN"; 123 //生成隨機AES對稱密鑰 124 String keyStr = generateRandomKey(16); 125 byte[] keyBytes = keyStr.getBytes("UTF-8"); 126 127 byte[] encryptAES = encryptAES(value.getBytes(), keyBytes, true, "UTF-8"); 128 129 System.out.println("AES加密後數據: "+new String(encryptAES)); 130 131 /*String encodeBase64String = Base64.encodeBase64String(encryptAES); 132 133 System.out.println("先AES後BASE64: "+encodeBase64String); 134 135 byte[] decodeBase64 = Base64.decodeBase64(encodeBase64String);*/ 136 137 byte[] decryptAES = decryptAES(encryptAES, keyBytes, true, "UTF-8"); 138 139 System.out.println("AES減密後數據: "+ new String(decryptAES)); 140 141 } 142 143 }
運行結果:算法