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)); } }