昨天呢写了一个非对称数据加密,今天来写对称的数据加密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里已经帮我们写好了这些加密算法的细节,所以很方便
最后推荐一下:
2.数据传输加密——非对称加密算法RSA+对称加密算法AES
https://github.com/MoisAbby/XZUtils