1.加密与解密
数据加密 的基本过程,就是对原来为 明文 的文件或数据按某种算法 进行处理,使其成为不可读的一段代码,通常称为 “密文”。通过这样的途径,来达到保护数据不被非法人窃取、阅读的目的。
加密的逆过程为解密,即将该编码信息转化为其原始数据的过程。
2.MD5

MD5即 Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。严格意义上讲,MD5不是加密算法,是散列算法,或者叫做哈希算法。 加密算法一般指对称加密算法。
MD5是一种摘要算法,所谓摘要算法:又称哈希算法、散列算法,它通过一个函数,把任意长度的数据转换为一个长度固定的数据串,摘要结果是不可逆的,不能被还原为原始数据。
MD5常见的应用场景如下:
除了MD5常见的摘要算法,还有SHA算法,包括SHA-1,SHA-2(SHA-224,SHA-256,SHA-384,SHA-512)等等。
3.对称加密

对称加密算法:加密算法与解密算法的秘钥KEY一致。发送和接收双方都使用这个密钥对数据进行加密和解密。这就要求加密和解密方事先都必须知道加密的密钥。
AES:Advanced Encryption Standard。是最常用的对称加密算法,由于其密钥建立时间短、灵敏性好、内存需求低,因此被广泛使用。
4.非对称加密
加密和解密使用的是两个不同的密钥,这种算法称为非对称加密算法。

例子:甲方生成 一对密钥 并将其中的一把作为 公钥 向其它人公开,得到该公钥的 乙方 使用该密钥对机密信息 进行加密 后再发送给甲方,甲方再使用自己保存的另一把 专用密钥 (私钥),对加密后的信息 进行解密。
RSA:RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的一种加密算法。
RSA公开密钥密码体制的原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
5.bcrypt加密
BCrypt加密:是一种类似MD5加盐的加密算法,但是与MD5加盐不同的是,每次会随机生成salt,salt再跟明文进行hash。
bcrypt加密有以下特点: - 对于同一个明文,每次生成的hash是不同的 - hash中包含了salt
bcrypt与md5对比如下:
|选项|MD5|Bcrypt|
|-|-|-|
|密文长度|32位|60位|
|安全性|安全性差。
密码相同时,加密后密文一样。
提升安全性的方案:加密前生成随机的盐值(字符串),将它与密码拼接,然后再使用md5加密。|安全性好。
密码相同时,生成的密文是不一样的。(因为它自动生成随机盐值)|
|加密耗时|短|略长|
实例
创建maven项目,添加如下依赖:
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.4</version>
</dependency>
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
</dependencies>
MD5摘要加密
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
/*MD5摘要加密算法*/
public class MD5Demo {
public static void main(String[] args) {
String pass1 = "Hello,Welcome to Beijing!I am a chinese.";
String pass2= "123456";
String pass3 = "123456";
Digester md5 = new Digester(DigestAlgorithm.MD5);
String pass1_md5 = SecureUtil.md5(pass1);
String pass2_md5 = SecureUtil.md5(pass2);
String pass3_md5 = md5.digestHex(pass3);
System.out.println("pass1_md5 value : " +pass1_md5);
System.out.println("pass2_md5 length : " +pass2_md5);
System.out.println("pass3_md5 length : " +pass3_md5);
System.out.println("pass1_md5 length = " + pass1_md5.length());
System.out.println("pass2_md5 length = " +pass2_md5.length());
System.out.println(pass1_md5.length() == pass2_md5.length());
}
}
SHA256摘要加密
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
/*SHA256摘要加密算法*/
public class SHADemo {
public static void main(String[] args) {
String pass1 = "Hello,Welcome to Beijing!I am a chinese.";
String pass2= "123456";
String pass3 = "123456";
Digester sha = new Digester(DigestAlgorithm.SHA256);
String pass1_sha = SecureUtil.sha256(pass1);
String pass2_sha = SecureUtil.sha256(pass2);
String pass3_sha = sha.digestHex(pass3);
System.out.println("pass1_sha value : " +pass1_sha);
System.out.println("pass2_sha length : " +pass2_sha);
System.out.println("pass3_sha length : " +pass3_sha);
System.out.println("pass1_sha length = " + pass1_sha.length());
System.out.println("pass2_sha length = " +pass2_sha.length());
System.out.println(pass1_sha.length() == pass2_sha.length());
}
}
AES对称加密算法
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import java.nio.charset.StandardCharsets;
/*AES对称加密算法*/
public class AESDemo {
public static void main(String[] args) {
String pass1 = "123456";
String pass2 = "123456";
//如果使用相同的私钥
byte[] secret_key = "assistant7654321".getBytes(StandardCharsets.UTF_8);
//随机生成密钥
byte[] key1 = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
//随机生成密钥
byte[] key2 = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
//构建
SymmetricCrypto aes1 = new SymmetricCrypto(SymmetricAlgorithm.AES, key1);
//构建
SymmetricCrypto aes2 = new SymmetricCrypto(SymmetricAlgorithm.AES, key2);
//密码加密
byte[] encrypt1 = aes1.encrypt(pass1);
byte[] encrypt2 = aes2.encrypt(pass2);
System.out.println("pass1 的密文:" +new String(encrypt1));
System.out.println("pass2 的密文:" +new String(encrypt2));
//密码解密
byte[] decrypt1 = aes1.decrypt(encrypt1);
byte[] decrypt2 = aes2.decrypt(encrypt2);
System.out.println("pass1 的明文:" +new String(decrypt1));
System.out.println("pass2 的明文:" +new String(decrypt2));
//加密为16进制表示
String encryptHex1 = aes1.encryptHex(pass1);
String encryptHex2 = aes2.encryptHex(pass2);
System.out.println("pass1 的密码16进制:" + encryptHex1);
System.out.println("pass2 的密码16进制:" + encryptHex2);
//解密为字符串
String decryptStr1 = aes1.decryptStr(encryptHex1, CharsetUtil.CHARSET_UTF_8);
System.out.println("pass1 的明文:" +decryptStr1);
String decryptStr2 = aes2.decryptStr(encryptHex2, CharsetUtil.CHARSET_UTF_8);
System.out.println("pass2 的明文:" +decryptStr2);
}
}
RSA非对称加密算法
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import java.security.PrivateKey;
import java.security.PublicKey;
/*RSA非对称加密算法*/
public class RSADemo {
public static void main(String[] args) {
RSA rsa = new RSA();
//获得私钥
PrivateKey privateKey= rsa.getPrivateKey();
String privateKeyStr = rsa.getPrivateKeyBase64();
System.out.println("私钥字符串:" + privateKeyStr);
//获得公钥
PublicKey publicKey = rsa.getPublicKey();
String publicKeyStr = rsa.getPublicKeyBase64();
System.out.println("公钥字符串:" + publicKeyStr);
//公钥加密,私钥解密
byte[] encrypt = rsa.encrypt(StrUtil.bytes("123456", CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey);
System.out.println("公钥加密,私钥解密=>解密后密码:"+ new String(decrypt));
//私钥加密,公钥解密
byte[] encrypt2 = rsa.encrypt(StrUtil.bytes("123456", CharsetUtil.CHARSET_UTF_8), KeyType.PrivateKey);
byte[] decrypt2 = rsa.decrypt(encrypt2, KeyType.PublicKey);
System.out.println("私钥加密,公钥解密=>解密后密码:"+ new String(decrypt2));
}
}
Bcrypt加密算法
import org.mindrot.jbcrypt.BCrypt;
/*Bcrypt加密算法*/
public class BcryptDemo {
public static void main(String[] args) {
String password = "123456";
// 加密
String encodedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
System.out.println("password 的密文:" +encodedPassword);
// 使用正确密码验证密码是否正确
boolean flag = BCrypt.checkpw(password, encodedPassword);
System.out.println(flag);
// 使用错误密码验证密码是否正确
flag = BCrypt.checkpw("111222", encodedPassword);
System.out.println(flag);
System.out.println("-------------------对相同密码再次加密------------------------");
//相同密文再次加密
encodedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
System.out.println("password 再次加密的密文:" +encodedPassword);
}
}
Bcrypt加密算法(基于Hutool工具类)
我们发现Hutool工具类内部就是使用了org.mindrot.jbcrypt.BCrypt,因此用法完全相同。
String password1 = "123456";
String password2 = "123456";
String encodePass1 = BCrypt.hashpw(password1);
String encodePass2 = BCrypt.hashpw(password2);
System.out.println(encodePass1);
System.out.println(encodePass2);
if(BCrypt.checkpw(password1,encodePass1)){
System.out.println("密码相同");
}else{
System.out.println("密码不同");
}
System.out.println("----------------------------");
if(BCrypt.checkpw(password1,encodePass2)){
System.out.println("密码相同");
}else{
System.out.println("密码不同");
}
System.out.println("----------------------------");
if(BCrypt.checkpw("12345",encodePass2)){
System.out.println("密码相同");
}else{
System.out.println("密码不同");
}
}