1. 介绍
在Java开发的过程中,很多场景下都需要加密解密。
比如对敏感数据的加密,对配置文件信息的加密,通信数据的加密等等。
今天介绍的是Hutool工具包中的加密模块 crypto。
2. 加密分类
加密分为三类:
-
对称加密(symmetric)
常用的有AES、DES
-
非对称加密(asymmetric)
常用的有RSA,DSA
-
摘要加密(digest)
常用的有MD5,SHA-1
3. crypto模块整体介绍
- 秘钥工具
- 加密解密工具
- BCUtil
- 国密算法SmUtil
4. 摘要加密(Digest)
4.1 间接
摘要算法是一种能产生特殊输出格式的算法,这种算法的特点是:无论用户输入设么长度的原始数据,讲过计算后输出的密文都是固定长度的,这种算法的原理是根据一定的运算规则进行某种形式的提取,这种提取就是摘要,比摘要的数据与元数据有密切联系。只要源数据稍有改变,输出的“摘要”便完全不同,因此,基于这种原理的额算法便能够对数据完整性提供健全的保证。
但是,由于输出的密文是提取元数据经过处理的定长值,所以他已经不能还原为原数据,即消息摘要算法是不可逆的。理论上无法通过反向运算取得元数据内容。因此他通常值能被用来做数据的完整性验证。
4.2 使用
这主要介绍md5加密。
基本使用
/**
* md5的基本使用
* 生成32位的密文
*/
@Test
public void MD5BasicTest() {
System.out.println(new String(DigestUtil.md5("testaaa")));
// 返回16进制形式 de2ec3065687316991579e6b9e6ce143
System.out.println(DigestUtil.md5Hex("testaa"));
}
加盐、加盐位置、摘要次数
/**
* md5的高级使用
* 加盐 加盐的位置 摘要次数
*/
@Test
public void MD5Test() {
// 加盐 加盐的位置 摘要次数
String salt = "md5Salt";
int index = 0;
int count = 2;
MD5 md5 = new MD5(salt.getBytes(StandardCharsets.UTF_8), index, count);
// 返回16进制格式
System.out.println(md5.digestHex("testaa"));;
}
5. 对称加密(Symmetric)
5.1 介绍
对称加密(也就私钥加密),指加密和解密使用相同秘钥的加密算法。有时又叫传统密码算法,就是加密米哟啊能够从解密秘钥中推算出来,同时秘钥也可以从加密秘钥中推算出来。而在大多数的对称算法中,加密秘钥和解密秘钥是相同的,所以也成这种算法为私密秘钥算法或者单秘钥算法。
她要求发送方和接收方在安全通信之前,商定一个秘钥。
对称算法的安全性依赖于秘钥,泄露秘钥就意味着任何人都可以对他们发送和接收的消息进行解密,所以秘钥的保密性对通信的安全性至关重要。
5.2 使用
这儿介绍AES
基本使用
/**
* 简单使用,直接使用秘钥加密解密
*/
@Test
public void AESBasicTest() {
// 生成秘钥,也可以手动指定
byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
// 构建
SymmetricCrypto symmetricCrypto = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
// 加密
System.out.println(new String(symmetricCrypto.encrypt("testaa")));
// 生成16进制格式的
System.out.println(symmetricCrypto.encryptHex("testaa"));
// 解密
System.out.println(new String(symmetricCrypto.decrypt(symmetricCrypto.encrypt("testaa"))));
// 直接解密字符串
System.out.println(symmetricCrypto.decryptStr(symmetricCrypto.encryptHex("testaa")));
}
高级使用
/**
* AES 高级使用
* mode – 模式Mode
* padding – Padding补码方式
* key – 密钥,支持三种密钥长度:128、192、256位
* iv – 偏移向量,加盐 必须16位
*
* 缺点,受到iv的影响,加密的字符串要么为空,要么为16位以上
*/
@Test
public void AESTest() {
// 生成秘钥,也可以手动指定
byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
String iv = "testiv0000000000";
AES aes = new AES(Mode.CTS, Padding.PKCS5Padding, key, iv.getBytes(StandardCharsets.UTF_8));
// 加密
System.out.println(aes.encryptHex("testaa1234567899"));
// 解密
System.out.println(aes.decryptStr(aes.encrypt("testaa1234567899")));
}
6. 非对称加密(Asymmetric)
6.1 介绍
对于非对称加密,最常用的就是RSA和DSA。
非堆成加密有公钥和私钥两个概念,私钥自己拥有,公钥公开。根据应用的不同,我们可以选择使用不同的秘钥进行加密。
- 签名:使用私钥加密,公钥解密。用于让所有公钥的所有者验证私钥所有者的身份并且用来防止私钥所有者发布的内容被篡改,但是不是用来保证内容不被他人获得的;
- 加密:用公钥加密,私钥解密。用于向公钥所有者发布星系,这个信息可能被他们篡改,但是无法被他人获取。
6.2 使用
这儿介绍RSA
基本使用
/**
* 基本使用
*/
@Test
public void RSABasicTest() {
RSA rsa = new RSA();
// 获取公钥和私钥
System.out.println(rsa.getPublicKey());
System.out.println(rsa.getPrivateKeyBase64());
System.out.println(rsa.getPrivateKey());
System.out.println(rsa.getPrivateKeyBase64());
// 私钥加密,公钥解密
System.out.println(new String(rsa.encrypt("testaa", KeyType.PrivateKey)));
System.out.println(new String(rsa.decrypt(rsa.encrypt("testaa", KeyType.PrivateKey), KeyType.PublicKey)));
// 公钥加密,私钥解密
System.out.println(new String(rsa.encrypt("testaa", KeyType.PublicKey)));
System.out.println(new String(rsa.decrypt(rsa.encrypt("testaa", KeyType.PublicKey), KeyType.PrivateKey)));
}
高级使用
/**
* 高级使用
* 自定义生成 公钥和私钥
*/
@Test
public void RSATest() {
KeyPair keyPair = SecureUtil.generateKeyPair(AsymmetricAlgorithm.RSA.getValue());
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
System.out.println(publicKey);
System.out.println(privateKey);
System.out.println("----------");
RSA rsa = new RSA(privateKey, publicKey);
// 私钥加密,公钥解密
System.out.println(new String(rsa.encrypt("testaa", KeyType.PrivateKey)));
System.out.println(new String(rsa.decrypt(rsa.encrypt("testaa", KeyType.PrivateKey), KeyType.PublicKey)));
// 公钥加密,私钥解密
System.out.println(new String(rsa.encrypt("testaa", KeyType.PublicKey)));
System.out.println(new String(rsa.decrypt(rsa.encrypt("testaa", KeyType.PublicKey), KeyType.PrivateKey)));
}
7. 国密算法(SM)
Hutool针对Bouncy Castle
做了简化包装,用于实现国密算法中的SM2、SM3、SM4。。
国密算法工具封装包括:
- 非对称加密和签名:SM2
- 摘要签名算法:SM3
- 对称加密:SM4
国密算法需要引入 Bouncy Castle
库的依赖。
这不做介绍了。