关于WannaCry,相信大家都有所了解,那是一种通过加密用户计算机中的文件,从而对用户进行勒索的病毒。
当然本文重点不是介绍WannaCry,而是通过这个来引出本文重点要说的加密解密。关于加密算法网上有很多文章介绍,感兴趣的可以自行查找相关文章进行学习。
加密和哈希的区别
当然,有很多人对于加密(Encrypt)和哈希(Hash)有所误解,认为哈希也是加密,其实是错误的观点。哈希是计算出一个散列值,这个散列值和源数据的每一个字节都有十分紧密的关系,但是就算你知道算法也很难找出逆推规律的;而加密你只要知道加密算法和秘钥,就能把密文逆向推理出明文数据的。
加密算法分类
-
对称式加密
对称式加密就是加密和解密使用同一个密钥,通常称之为“Session Key ”这种加密技术在当今被广泛采用,如DES加密标准就是一种典型的“对称式”加密法,它的Session Key长度为56bits。 -
非对称式加密
非对称式加密就是加密和解密所使用的不是同一个密钥,通常有两个密钥,称为“公钥”和“私钥”,它们两个必需配对使用,否则不能打开加密文件。这里的“公钥”是指可以对外公布的,“私钥”则不能,只能由持有人一个人知道。它的优越性就在这里,因为对称式的加密方法如果是在网络上传输加密文件就很难不把密钥告诉对方,不管用什么方法都有可能被别窃听到。而非对称式的加密方法有两个密钥,且其中的“公钥”是可以公开的,也就不怕别人知道,收件人解密时只要用自己的私钥即可以,这样就很好地避免了密钥的传输安全性问题。
AES加密算法
AES(Advanced Encryption Standard)加密算法就是属于对称式的加密算法,AES的特点是速度快,安全级别高。具体加密解密流程如下:
代码实现
首先定义一个AESUtils
工具类,这是本文用到的核心类
package com.feonix.util;
import javax.crypto.*;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* AESUtils
*
* @author FeoniX
* @date 2020/12/29 下午5:11
* @description AES加密解密工具类
*/
public class AESUtils {
// 随机数生成器算法
private static final String SECURE_RANDOM_ALGORITHM = "SHA1PRNG";
// 加密算法
private static final String CIPHER_ALGORITHM = "AES";
// 生成秘钥长度
private static final Integer KEY_SIZE = 128;
/**
* 生成秘钥
*
* @param password 用户自定义密码
* @return
* @throws NoSuchAlgorithmException
*/
private static SecretKey generateSecretKey(String password) throws NoSuchAlgorithmException {
// 根据指定的 RNG 算法, 创建安全随机数生成器
SecureRandom random = SecureRandom.getInstance(SECURE_RANDOM_ALGORITHM);
// 设置 密钥password的字节数组 作为安全随机数生成器的种子
random.setSeed(password.getBytes());
// 创建 AES算法生成器
KeyGenerator gen = KeyGenerator.getInstance(CIPHER_ALGORITHM);
// 初始化算法生成器
gen.init(KEY_SIZE, random);
// 生成 AES密钥对象
return gen.generateKey();
}
/**
* 加密
*
* @param plainBytes 明文字节码
* @param password 用户自定义密码
* @return 密文字节码
*/
public static byte[] encrypt(byte[] plainBytes, String password) {
// 生成密钥对象
SecretKey secKey = null;
try {
secKey = generateSecretKey(password);
// 获取 AES 密码器
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化密码器(加密模型)
cipher.init(Cipher.ENCRYPT_MODE, secKey);
// 加密数据, 返回密文
return cipher.doFinal(plainBytes);
} catch (NoSuchAlgorithmException e) {
System.out.println("No Such Algorithm Exception");
} catch (NoSuchPaddingException e) {
System.out.println("No Such Padding Exception");
} catch (InvalidKeyException e) {
System.out.println("Invalid Key Exception");
} catch (IllegalBlockSizeException e) {
System.out.println("Illegal Block Size Exception");
} catch (BadPaddingException e) {
System.out.println("Bad Padding Exception");
}