AES產生背景:
DES的安全性和應用前景受到挑戰,因此需要設計一個高保密性能的、算法公開的、全球免費使用的分組密碼算法,用於保護敏感信息,並希望以此新算法取代DES算法,稱為新一代數據加密標准,取名為高級數據加密標准(AES)
AES算法並不是一個具體的算法,而是一個算法的標准,它的要求和評估准則:
1.AES基本要求:比DES快且比DES安全,分組長度為128比特,密鑰長度為128/192/256。
2.安全性評估:算法輸出的隨機性好,抗密碼分析能力強,並且有可靠的數學基礎。
3.成本估計准則:許可成本低,在各種平台上的計算高效率和較小的內存空間需求。
4.算法和實現特性准則:靈活性、硬件和軟件使用性、算法的簡明性。具體體現為:算法處理的密鑰和分組長度必須具備靈活的支持范圍;算法在許多不同類型的環境下能夠安全和有效地實現;可以作為序列密碼、哈希算法實現;必須能夠用軟件和硬件兩種方法實現,並且有利於有效的固件實現;算法設計相對簡單。
1997年4月15日美國國家標准技術研究所發起征集AES算法的活動.並專門成立了AES工作組織,並在 1997年9月12日在聯邦登記處公布了征集AES候選算法的通告。
2000年10月2日正式公布比利時Rijmen 和Daemen設計的Rijndael算成為AES算法。
Rijndael優點:
NIST發表了一篇長達116頁的報含,總結了選擇Rijndael為AES的理由:
無論使用反饋模式還無反饋模式,在廣泛的計算環境的硬件和軟件實現件能都始終有着優秀的表現;
它的密鑰建立時間極短,且靈敏性良好;
極低的內存需求使它非常適合於在存儲器受限的環境中使用;
運算易於抵抗強力和時間選擇攻擊;
算法的內部循環結構將會從指令級並行處理中獲得潛在的益處。
加密的模型:
組合起來就是一個AES塊
AES中塊長度, 密鑰長度和輪數關系
Nb、Nk:塊長度(以word為單位,一個word 32位注意上面的圖)
Nr:輪數
子密鑰矩陣長度:Nb*(Nr+1)
加密的偽代碼:
SubBytes步驟中有一個稱為S-box的表:
根據計算的結果將結果替換成S-box中相應的的值,比如計算出{53},x=5,y=3,對應的是{ed},用{ed}替換{53}
ShiftRows:
MixColumns:
AddRoundKey:
對每一列進行和密鑰對應列的異或運算
解密過程基本上相當於加密逆過程:
偽代碼如下:
S-box相應變化:
本文只是對AES進行了簡單的介紹,根據AES的詳細介紹文件來編寫的。水平有限,解釋的不清楚。
如果想對AES有更系統詳細的了解,建議閱讀該文檔http://files.cnblogs.com/files/13jhzeng/AnnouncingTheAES.pdf。
最后,附上java里使用AES的小例子:
public class EncryptAES { //KeyGenerator提供對稱密鑰生成器的功能,支持各種算法 private KeyGenerator keygen; //SecretKey負責保存對稱密鑰 private SecretKey seckey; //Cilher負責完成加密或解密工作 private Cipher c; //該字節數組負責保存加密的結果 private byte[] cipherByte; public EncryptAES() throws NoSuchAlgorithmException,NoSuchPaddingException { Security.addProvider(new com.sun.crypto.provider.SunJCE()); //實例化支持AES算法的密鑰生成器 keygen = KeyGenerator.getInstance("AES"); //生成密鑰 seckey = keygen.generateKey(); //生成Cipher對象,指定其支持AES算法 c = Cipher.getInstance("AES"); } /** * 對字符串加密 * * @param str * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] Encrytor(String str) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根據密鑰,對Cipher對象進行初始化,ENCRYPT_MODE表示加密模式 c.init(Cipher.ENCRYPT_MODE, seckey); byte[] src = str.getBytes(); // 加密,結果保存進cipherByte cipherByte = c.doFinal(src); return cipherByte; } /** * 對字符串解密 * * @param buff * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] Decryptor(byte[] buff) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根據密鑰,對Cipher對象進行初始化,DECRYPT_MODE表示加密模式 c.init(Cipher.DECRYPT_MODE, seckey); cipherByte = c.doFinal(buff); return cipherByte; } /** * @param args * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */ public static void main(String[] args) throws Exception { EncryptAES de1 = new EncryptAES(); String msg ="Hi,13jhzeng"; byte[] encontent = de1.Encrytor(msg); byte[] decontent = de1.Decryptor(encontent); System.out.println("明文是:" + msg); System.out.println("加密后:" + new String(encontent)); System.out.println("解密后:" + new String(decontent)); } }