昨天呢写了一个非对称数据加密,今天来写对称的数据加密AES。对称数据加密就是只使用一个密钥 进行加密和解密,AES可以使用128,192,和256位密钥。
然后就是我的工具类:
public class AESUtil {
public static byte[] getKeys(String data){
try {
// 创建AES的Key生产者
KeyGenerator kgen = KeyGenerator.getInstance("AES");
// 利用用户密码作为随机数初始化出128位的key生产者
//SecureRandom 是生成安全随机数序列,password.getBytes() 是种子,只要种子相同,序列就一样,密钥也一样
kgen.init(128, new SecureRandom(data.getBytes()));
// 根据用户密码,生成一个密钥
SecretKey secretKey = kgen.generateKey();
byte[] key = secretKey.getEncoded();
return key;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
System.out.println("没有此算法");
}
return null;
}
public static byte[] getKeys(){
try {
// 创建AES的Key生产者
KeyGenerator kgen = KeyGenerator.getInstance("AES");
// 利用用户密码作为随机数初始化出128位的key生产者
//SecureRandom 是生成安全随机数序列,没有种子
kgen.init(128);
SecretKey secretKey = kgen.generateKey();
byte[] key = secretKey.getEncoded();
return key;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
System.out.println("没有此算法");
}
return null;
}
/**
* @param content
* @param secretkey
* @return
*/
public static byte[] encrypt(String content, byte[] secretkey) {
try {
// 转换为AES专用密钥
SecretKeySpec key = new SecretKeySpec(secretkey, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化为加密模式的密码器
byte[] result = cipher.doFinal(byteContent);// 加密
return result;
} catch (Exception e){
e.printStackTrace();
}
return null;
}
public static byte[] decrypt(byte[] content, SecretKey secretKey) {
try {
byte[] enCodeFormat = secretKey.getEncoded();
// 转换为AES专用密钥
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
// 创建密码器
Cipher cipher = Cipher.getInstance("AES");
// 初始化为解密模式的密码器
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] result = cipher.doFinal(content);
// 明文
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static byte[] decrypt(byte[] content, byte[] secretKey) {
try {
// 转换为AES专用密钥
SecretKeySpec key = new SecretKeySpec(secretKey, "AES");
// 创建密码器
Cipher cipher = Cipher.getInstance("AES");
// 初始化为解密模式的密码器
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] result = cipher.doFinal(content);
// 明文
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String content = "我是-桃之夭夭";
String password = "767";
System.out.println("加密之前:" + content);
byte[] key = getKeys();
// 加密
byte[] encrypt = AESUtil.encrypt(content, key);
System.out.println("加密后的内容:" + Base64.encodeBase64URLSafeString(encrypt));
// 解密
byte[] decrypt = AESUtil.decrypt(encrypt, key);
System.out.println("解密后的内容:" + new String(decrypt));
}
}
这个过程就是随机生成一个密钥(可以有种子,也可以没有),然后用这个密钥加密和解密,还是很简单的啦(●ˇ∀ˇ●)
然后为了安全常常是RSA和AES一起使用,一般来讲就是:
客户端加密:
1. 随机产生AES密钥;
2. 对重要信息进行AES加密
3. 使用RSA对AES密钥进行公钥加密
服务端解密:
1. 使用RSA私钥对AES密钥解密
2. 用AES密钥对重要信息的密文解密
所以我又模拟了一下这个过程:
public class AES_RSAUtil {
public static void main(String[] args) throws Exception{
/*模拟客户端*/
String msg = "hello 冬竹";
byte[] key = AESUtil.getKeys();//获取密钥的编码
byte[] bytes = AESUtil.encrypt(msg,key);
String seKey = Base64.encodeBase64URLSafeString(key);//转成字符串之后进行再加密
RSAUtil.init();
//RSA公钥 加密后的 AES密钥
String encryptKey = RSAUtil.encryptByPublicKey(seKey,RSAUtil.getPublicKey(RSAUtil.keyMap.get("PUBLIC_KEY")));
/*模拟服务端*/
//解码AES密钥
String aesKey = RSAUtil.decryptByPrivateKey(encryptKey,RSAUtil.getPrivateKey(RSAUtil.keyMap.get("PRIVATE_KEY")));
//还原aesKey
byte[] secretKey = Base64.decodeBase64(aesKey);
String ming = new String(AESUtil.decrypt(bytes,secretKey));
System.out.println(ming);
}
这个用到的依赖什么的都是我昨天的那个啦,好了,因为Java的jdk里已经帮我们写好了这些加密算法的细节,所以很方便