簡介
AES 的出現(xiàn)赏寇,就是為了來替代原先的 DES 標(biāo)準(zhǔn)∩星ⅲ現(xiàn)在來說,AES 的用途還是非常廣泛的蒸其。
全稱為“Advanced Encryption Standard”,中文名“高級加密標(biāo)準(zhǔn)”库快,在密碼學(xué)中又稱 Rijndael 加密法枣接,是美國聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。AES 加密算法作為新一代的數(shù)據(jù)加密標(biāo)準(zhǔn)匯聚了強(qiáng)安全性缺谴、高性能但惶、高效率、易用和靈活等優(yōu)點湿蛔。AES 設(shè)計有三個密鑰長度:128膀曾,192,256 位阳啥。相對而言添谊,AES 的 128 密鑰比 DES 的 56 密鑰強(qiáng)了 1021 倍。
相對來說察迟,如果密鑰長度變長斩狱,那么IV向量的長度對應(yīng)的也要變長才行。應(yīng)為對于塊加密來說扎瓶,密鑰長度和IV向量的長度應(yīng)該是一致的所踊。
原理
ES 加密算法主要包括三個方面:輪變化、圈數(shù)和密鑰擴(kuò)展概荷。AES 是分組密鑰秕岛,算法輸入 128 位數(shù)據(jù),密鑰長度也是 128 位。用 Nr 表示對一個數(shù)據(jù)分組加密的輪數(shù)继薛。每一輪都需要一個與輸入分組具有相同長度的擴(kuò)展密鑰 Expandedkey(i) 的參與修壕。由于外部輸入的加密密鑰 K 長度有限,所以在算法中要用一個密鑰擴(kuò)展程序 (Keyexpansion) 把外部密鑰 K 擴(kuò)展成更長的比特串遏考,以生成各輪的加密和解密密鑰慈鸠。
輸出
入口參數(shù)有三個:key、data灌具、mode林束。
- key 為加密解密使用的密鑰,長度為24字節(jié)
- data 為加密 解密的數(shù)據(jù)稽亏,
- mode 為其工作模式。
密鑰是192位缕题,但是是分開使用的截歉,每個加密快的長度應(yīng)該還是8字節(jié)的整數(shù)倍
記住:如果是有padding烟零,如果是明文如果是8字節(jié)的整數(shù)倍的話瘪松,加密的密文長度肯定要增加8個字節(jié),因為要有標(biāo)識
java demo
注意锨阿,如果是使用的cfb宵睦,ofb等需要初始化向量的加解密,則需要把iv也傳給解密器才行
/**
* 加密
*
* @param content 需要加密的內(nèi)容
* @param password 加密密碼
* @return
*/
public static byte[] encrypt(String content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 創(chuàng)建密碼器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
return result; // 加密
} 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;
}
2.2 解密
代碼有詳細(xì)注釋墅诡,不多廢話
注意:解密的時候要傳入byte數(shù)組
[java] view plain copy
/**解密
* @param content 待解密內(nèi)容
* @param password 解密密鑰
* @return
*/
public static byte[] decrypt(byte[] content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 創(chuàng)建密碼器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
return result; // 加密
} 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();
}
return null;
}
/**解密
* @param content 待解密內(nèi)容
* @param password 解密密鑰
* @return
*/
public static byte[] decrypt(byte[] content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 創(chuàng)建密碼器
// Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");// 這里使用的是這種方式的話壳嚎,在下面的init處就會報錯,因為沒有傳入iv向量
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
return result; // 加密
} 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();
}
return null;
}