2.3 AES算法简介
2018-11-29 本文已影响0人
saillen
对称加密技术 - AES加密
AES的产生目标是替代DES(包括3DES)的,一般情况先推荐优先使用AES算法加加密;
AES发展历史
- 1997年NIST发起了整机替代DES算法的活动:高级数据加密标准(Advanced Encryption Standard);
- NIST要求算法比3DES快、安全性、具有128位分组长度、支持128/192/256位长度的密钥;
- 2000年Rijndael算法当选AES算法标准;
- AES:密钥建立时间短、灵敏性好、内存需求低,被广泛应用;
- AES根据密钥长度分为AES-128、AES-256几种。
应用
AES
是用来替代DES的,所以凡是可以使用DES
的地方都应该优先考虑使用AES
替换,DES
作为遗留系统或者学习保留,实际建议使用AES
,一般场景AES-128
即可,高安全场景可以使用AES-256
.
在JDK中若要使用256的加密方式需要:无政策性限制权限文件。
Java中使用步骤
AES
的使用和DES
一样,也是经过三步,Java的API封装的很好,使用SPI机制实现策略模式,外部代码改动很小。
在使用其他对称加密算法:RC2、RC4、Blowfish算法的时候都可以参照下面的模式。
- 构建密钥:使用
KeyGenerator
,这个步骤对称加密算法和非对称加密算法都需要; - 构建
AES
专用的SecretKey
:和DES
和3DES
不同,使用SecretKeySpec
即可,这步是针对存储下来的密钥进行处理; - 进行加解密:要注意设置
Cipher
的工作模式。
整体代码如下:
public class AESTest {
// private static final String CIPHER_ALGORITHM = "DESede";
private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
private static final String KEY_ALGORITHM = "AES";
public static void main(String[] args) throws Exception {
// 产生Key,一般只产生一次,Base64工具采用的是JDK 8自带的工具
byte[] key = generateKey();
String keyStr = Base64.getEncoder().encodeToString(key);
String input = "加密我";
// 加密数据
byte[] encryptData = encrypt(input.getBytes(), key);
// 解密数据
byte[] dencryData = decrypt(encryptData, key);
String msg = String.format("原始数据: %s , Key : %s , 加密数据: %s , 解密数据: %s", input, keyStr,
HexBin.encode(encryptData), new String(dencryData));
System.out.println(msg);
}
/**
* 产生符合要求的Key,如果不用KeyGenerator随机性不好,而且要求自己对算法比较熟悉,能产生符合要求的Key
*
* @return
* @throws NoSuchAlgorithmException
*/
public static byte[] generateKey() throws NoSuchAlgorithmException {
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
// 3DES要求使用112或者168位密钥
// kg.init(112);
kg.init(128);
SecretKey secretKey = kg.generateKey();
byte[] key = secretKey.getEncoded();
return key;
}
/**
* 获取算法需要的安全密钥,这步比DES和3DES简单
*
* @param key
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
*/
public static SecretKey getSecretKey(byte[] key)
throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
SecretKey keySpec = new SecretKeySpec(key, KEY_ALGORITHM);
return keySpec;
}
/**
* 加密数据
*
* @param input
* @param key
* @return
* @throws Exception
*/
public static byte[] encrypt(byte[] input, byte[] key) throws Exception {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));
return cipher.doFinal(input);
}
/**
* 解密数据
*
* @param input
* @param key
* @return
* @throws Exception
*/
public static byte[] decrypt(byte[] input, byte[] key) throws Exception {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
return cipher.doFinal(input);
}
}