一、加密算法
类型 | 用途 | 特点 | 示例 | 推荐使用 | 安全性评价 | 适用场景 |
---|---|---|---|---|---|---|
对称加密 | 加密大量数据 | 加密解密速度快,密钥管理难 | DES | 否 | 弱 | 老旧系统兼容性 |
3DES | 否 | 中 | 有限制的老旧系统 | |||
AES (Rijndael) | 是 | 强 | 大量数据加密,现代应用 | |||
SM4 (SMS4) | 是 | 强 | 国密标准,国内应用 | |||
Blowfish | 否 | 中 | 小规模应用 | |||
非对称加密 | 安全通信,数字签名 | 安全性高,但速度慢 | RSA | 是 | 强 | 数字签名,密钥交换 |
ECC (Elliptic Curve Cryptography) | 是 | 强 | 密钥交换,移动设备 | |||
散列函数 | 数据完整性校验,密码存储 | 单向,不可逆 | MD5 | 否 | 弱 | 消息摘要(非安全性要求) |
SHA-1 | 否 | 弱 | 消息摘要(非安全性要求) | |||
SHA-256 | 是 | 强 | 安全消息摘要,密码哈希 | |||
SM3 | 是 | 强 | 国密标准,国内应用 | |||
编码 | 编码二进制数据为文本形式 | 不是加密,可逆转换 | Base64 | 否 | N/A | 传输二进制数据,邮件附件等 |
备注:
- DES:由于密钥长度较短(56位),已经容易受到攻击,因此不再推荐使用。
- 3DES:通过使用三倍的密钥长度来增强安全性,但在性能上不如AES。
- AES:是目前最广泛使用的对称加密算法之一,支持128、192和256位密钥长度。
- SM4:是中国国家密码管理局制定的一种分组密码算法,适用于国内应用。
- RSA:是一种非常常见的非对称加密算法,广泛用于数字签名和密钥交换。
- ECC:与RSA相比,在相同安全水平下可以使用更短的密钥,更适合移动设备。
- MD5 和 SHA-1:由于已知的碰撞攻击,不再推荐用于安全性要求高的场合。
- SHA-256:是目前较为安全的散列函数之一,适合用于密码存储和其他需要高强度散列的应用。
- Base64:是一种编码方式,而不是加密算法,主要用于将二进制数据转换为可以在文本环境中安全传输的形式。
二、工具类展示
public class EncryptUtils {
/**
* 公钥
*/
public static final String PUBLIC_KEY = "publicKey";
/**
* 私钥
*/
public static final String PRIVATE_KEY = "privateKey";
/**
* Base64加密
*
* @param data 待加密数据
* @return 加密后字符串
*/
public static String encryptByBase64(String data) {
return Base64.encode(data, StandardCharsets.UTF_8);
}
/**
* Base64解密
*
* @param data 待解密数据
* @return 解密后字符串
*/
public static String decryptByBase64(String data) {
return Base64.decodeStr(data, StandardCharsets.UTF_8);
}
/**
* AES加密
*
* @param data 待解密数据
* @param password 秘钥字符串
* @return 加密后字符串, 采用Base64编码
*/
public static String encryptByAes(String data, String password) {
if (StrUtil.isBlank(password)) {
throw new IllegalArgumentException("AES需要传入秘钥信息");
}
// aes算法的秘钥要求是16位、24位、32位
int[] array = {16, 24, 32};
if (!ArrayUtil.contains(array, password.length())) {
throw new IllegalArgumentException("AES秘钥长度要求为16位、24位、32位");
}
return SecureUtil.aes(password.getBytes(StandardCharsets.UTF_8)).encryptBase64(data, StandardCharsets.UTF_8);
}
/**
* AES加密
*
* @param data 待解密数据
* @param password 秘钥字符串
* @return 加密后字符串, 采用Hex编码
*/
public static String encryptByAesHex(String data, String password) {
if (StrUtil.isBlank(password)) {
throw new IllegalArgumentException("AES需要传入秘钥信息");
}
// aes算法的秘钥要求是16位、24位、32位
int[] array = {16, 24, 32};
if (!ArrayUtil.contains(array, password.length())) {
throw new IllegalArgumentException("AES秘钥长度要求为16位、24位、32位");
}
return SecureUtil.aes(password.getBytes(StandardCharsets.UTF_8)).encryptHex(data, StandardCharsets.UTF_8);
}
/**
* AES解密
*
* @param data 待解密数据
* @param password 秘钥字符串
* @return 解密后字符串
*/
public static String decryptByAes(String data, String password) {
if (StrUtil.isBlank(password)) {
throw new IllegalArgumentException("AES需要传入秘钥信息");
}
// aes算法的秘钥要求是16位、24位、32位
int[] array = {16, 24, 32};
if (!ArrayUtil.contains(array, password.length())) {
throw new IllegalArgumentException("AES秘钥长度要求为16位、24位、32位");
}
return SecureUtil.aes(password.getBytes(StandardCharsets.UTF_8)).decryptStr(data, StandardCharsets.UTF_8);
}
/**
* sm4加密
*
* @param data 待加密数据
* @param password 秘钥字符串
* @return 加密后字符串, 采用Base64编码
*/
public static String encryptBySm4(String data, String password) {
if (StrUtil.isBlank(password)) {
throw new IllegalArgumentException("SM4需要传入秘钥信息");
}
// sm4算法的秘钥要求是16位长度
int sm4PasswordLength = 16;
if (sm4PasswordLength != password.length()) {
throw new IllegalArgumentException("SM4秘钥长度要求为16位");
}
return SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8)).encryptBase64(data, StandardCharsets.UTF_8);
}
/**
* sm4加密
*
* @param data 待加密数据
* @param password 秘钥字符串
* @return 加密后字符串, 采用Base64编码
*/
public static String encryptBySm4Hex(String data, String password) {
if (StrUtil.isBlank(password)) {
throw new IllegalArgumentException("SM4需要传入秘钥信息");
}
// sm4算法的秘钥要求是16位长度
int sm4PasswordLength = 16;
if (sm4PasswordLength != password.length()) {
throw new IllegalArgumentException("SM4秘钥长度要求为16位");
}
return SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8)).encryptHex(data, StandardCharsets.UTF_8);
}
/**
* sm4解密
*
* @param data 待解密数据
* @param password 秘钥字符串
* @return 解密后字符串
*/
public static String decryptBySm4(String data, String password) {
if (StrUtil.isBlank(password)) {
throw new IllegalArgumentException("SM4需要传入秘钥信息");
}
// sm4算法的秘钥要求是16位长度
int sm4PasswordLength = 16;
if (sm4PasswordLength != password.length()) {
throw new IllegalArgumentException("SM4秘钥长度要求为16位");
}
return SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8)).decryptStr(data, StandardCharsets.UTF_8);
}
/**
* 产生sm2加解密需要的公钥和私钥
*
* @return 公私钥Map
*/
public static Map<String, String> generateSm2Key() {
Map<String, String> keyMap = new HashMap<>(2);
SM2 sm2 = SmUtil.sm2();
keyMap.put(PRIVATE_KEY, sm2.getPrivateKeyBase64());
keyMap.put(PUBLIC_KEY, sm2.getPublicKeyBase64());
return keyMap;
}
/**
* sm2公钥加密
*
* @param data 待加密数据
* @param publicKey 公钥
* @return 加密后字符串, 采用Base64编码
*/
public static String encryptBySm2(String data, String publicKey) {
if (StrUtil.isBlank(publicKey)) {
throw new IllegalArgumentException("SM2需要传入公钥进行加密");
}
SM2 sm2 = SmUtil.sm2(null, publicKey);
return sm2.encryptBase64(data, StandardCharsets.UTF_8, KeyType.PublicKey);
}
/**
* sm2公钥加密
*
* @param data 待加密数据
* @param publicKey 公钥
* @return 加密后字符串, 采用Hex编码
*/
public static String encryptBySm2Hex(String data, String publicKey) {
if (StrUtil.isBlank(publicKey)) {
throw new IllegalArgumentException("SM2需要传入公钥进行加密");
}
SM2 sm2 = SmUtil.sm2(null, publicKey);
return sm2.encryptHex(data, StandardCharsets.UTF_8, KeyType.PublicKey);
}
/**
* sm2私钥解密
*
* @param data 待加密数据
* @param privateKey 私钥
* @return 解密后字符串
*/
public static String decryptBySm2(String data, String privateKey) {
if (StrUtil.isBlank(privateKey)) {
throw new IllegalArgumentException("SM2需要传入私钥进行解密");
}
SM2 sm2 = SmUtil.sm2(privateKey, null);
return sm2.decryptStr(data, KeyType.PrivateKey, StandardCharsets.UTF_8);
}
/**
* 产生RSA加解密需要的公钥和私钥
*
* @return 公私钥Map
*/
public static Map<String, String> generateRsaKey() {
Map<String, String> keyMap = new HashMap<>(2);
RSA rsa = SecureUtil.rsa();
keyMap.put(PRIVATE_KEY, rsa.getPrivateKeyBase64());
keyMap.put(PUBLIC_KEY, rsa.getPublicKeyBase64());
return keyMap;
}
/**
* rsa公钥加密
*
* @param data 待加密数据
* @param publicKey 公钥
* @return 加密后字符串, 采用Base64编码
*/
public static String encryptByRsa(String data, String publicKey) {
if (StrUtil.isBlank(publicKey)) {
throw new IllegalArgumentException("RSA需要传入公钥进行加密");
}
RSA rsa = SecureUtil.rsa(null, publicKey);
return rsa.encryptBase64(data, StandardCharsets.UTF_8, KeyType.PublicKey);
}
/**
* rsa公钥加密
*
* @param data 待加密数据
* @param publicKey 公钥
* @return 加密后字符串, 采用Hex编码
*/
public static String encryptByRsaHex(String data, String publicKey) {
if (StrUtil.isBlank(publicKey)) {
throw new IllegalArgumentException("RSA需要传入公钥进行加密");
}
RSA rsa = SecureUtil.rsa(null, publicKey);
return rsa.encryptHex(data, StandardCharsets.UTF_8, KeyType.PublicKey);
}
/**
* rsa私钥解密
*
* @param data 待加密数据
* @param privateKey 私钥
* @return 解密后字符串
*/
public static String decryptByRsa(String data, String privateKey) {
if (StrUtil.isBlank(privateKey)) {
throw new IllegalArgumentException("RSA需要传入私钥进行解密");
}
RSA rsa = SecureUtil.rsa(privateKey, null);
return rsa.decryptStr(data, KeyType.PrivateKey, StandardCharsets.UTF_8);
}
/**
* md5加密
*
* @param data 待加密数据
* @return 加密后字符串, 采用Hex编码
*/
public static String encryptByMd5(String data) {
return SecureUtil.md5(data);
}
/**
* sha256加密
*
* @param data 待加密数据
* @return 加密后字符串, 采用Hex编码
*/
public static String encryptBySha256(String data) {
return SecureUtil.sha256(data);
}
/**
* sm3加密
*
* @param data 待加密数据
* @return 加密后字符串, 采用Hex编码
*/
public static String encryptBySm3(String data) {
return SmUtil.sm3(data);
}
}
三、base64加密解密测试
public static void main(String[] args) {
String data = "1234Hello你好";
String password = "syf12345abcdefgh";
//base64(data, null);
//aes(data, password);
sm4(data,password);
}
public static void base64(String data, String password) {
//base64 加密
String s = EncryptUtils.encryptByBase64(data);
Console.log("加密前{},加密后:{}", data, s);
String decryptByBase64 = EncryptUtils.decryptByBase64(s);
Console.log("解密后:{}", decryptByBase64);
}
结果:
加密前1234Hello你好,加密后:lOiWz7uObJr2w0uZ847SLg==
解密后:1234Hello你好
四、aes加密测试
public static void main(String[] args) {
String data = "1234Hello你好";
String password = "syf12345abcdefgh";
//base64(data, null);
aes(data, password);
//sm4(data,password);
}
public static void aes(String data, String password) {
String encryptByAes = EncryptUtils.encryptByAes(data, password);
Console.log("加密前{},加密后:{}", data, encryptByAes);
String decryptByAes = EncryptUtils.decryptByAes(encryptByAes, password);
Console.log("解密后:{}", decryptByAes);
}
结果:
加密前1234Hello你好,加密后:xecPhHDI0cjQ6mXRD8oNZQ==
解密后:1234Hello你好
五、sm4加密
public static void main(String[] args) {
String data = "1234Hello你好";
String password = "syf12345abcdefgh";
//base64(data, null);
//aes(data, password);
sm4(data,password);
}
public static void sm4(String data, String password) {
String encryptBySm4 = EncryptUtils.encryptBySm4(data, password);
Console.log("加密前{},加密后:{}", data, encryptBySm4);
String decryptBySm4 = EncryptUtils.decryptBySm4(encryptBySm4, password);
Console.log("解密后:{}", decryptBySm4);
}
结果:
加密前1234Hello你好,加密后:lOiWz7uObJr2w0uZ847SLg==
解密后:1234Hello你好
六、sm2
非对称的加密,需要生成公钥和私钥
- 公钥:用于加密
- 私钥:用于解密
public static void main(String[] args) {
String data = "1234Hello你好";
String password = "syf12345abcdefgh";
//base64(data, null);
//aes(data, password);
//sm4(data,password);
sm2(data);
}
public static void sm2(String data) {
Map<String, String> stringStringMap = EncryptUtils.generateSm2Key();
String PUBLIC_KEY = stringStringMap.get(EncryptUtils.PUBLIC_KEY);
String PRIVATE_KEY = stringStringMap.get(EncryptUtils.PRIVATE_KEY);
Console.log("公钥:{},私钥:{}", stringStringMap.get(EncryptUtils.PUBLIC_KEY), stringStringMap.get(EncryptUtils.PRIVATE_KEY));
String encryptBySm2 = EncryptUtils.encryptBySm2(data, PUBLIC_KEY);
Console.log("加密前{},加密后:{}", data, encryptBySm2);
String decryptBySm2 = EncryptUtils.decryptBySm2(encryptBySm2, PRIVATE_KEY);
Console.log("解密后:{}", decryptBySm2);
}
结果:
公钥:MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEHnmRl9VcL+L8V6DDjVzMVW7hZrPniO8dPeuhXm0q0VFX6NjSIxcEXIFASuj50pLdADKHbtkUGirLxAdmcOnzXQ==,私钥:MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgaS7olpPUXGl0tH8edrtKHQpUkY80USDigi6FQgruZxugCgYIKoEcz1UBgi2hRANCAAQeeZGX1Vwv4vxXoMONXMxVbuFms+eI7x0966FebSrRUVfo2NIjFwRcgUBK6PnSkt0AModu2RQaKsvEB2Zw6fNd
加密前1234Hello你好,加密后:BN27hRUlX0e8XDV8EOStwYu9WcEyhusiQyrv+2s+k53ZDF5CRG7pa2m5KJ/oy7y8M0Kdcvc0yfZQ0X2eZhdbV72+wSeUw+am1G/1ppuWlaPK4N3bdxEfTUypyCd2R/nj0BPup1pYbhCNoHA1CTk+fA==
解密后:1234Hello你好
七、rsa加密
非对称的加密,需要生成公钥和私钥
- 公钥:用于加密
- 私钥:用于解密
public static void main(String[] args) {
String data = "1234Hello你好";
String password = "syf12345abcdefgh";
//base64(data, null);
//aes(data, password);
//sm4(data,password);
//sm2(data);
rsa(data);
}
/**
* <简述>rsa 非对称加密
* <详细描述>
* @author syf
* @date 2024/9/15 20:56
* @param data
*/
public static void rsa(String data) {
Map<String, String> stringStringMap = EncryptUtils.generateRsaKey();
String PUBLIC_KEY = stringStringMap.get(EncryptUtils.PUBLIC_KEY);
String PRIVATE_KEY = stringStringMap.get(EncryptUtils.PRIVATE_KEY);
Console.log("公钥:{}", stringStringMap.get(EncryptUtils.PUBLIC_KEY));
Console.log("私钥:{}", stringStringMap.get(EncryptUtils.PRIVATE_KEY));
String encryptByRsa = EncryptUtils.encryptByRsa(data, PUBLIC_KEY);
Console.log("加密前{},加密后:{}", data, encryptByRsa);
String decryptByRsa = EncryptUtils.decryptByRsa(encryptByRsa, PRIVATE_KEY);
Console.log("解密后:{}", decryptByRsa);
}
结果:
公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPh30Du4VVPjxsXW/Bn6B7o2Ye0lBj51Ag3hCMKO/NeF6MD1zNq2uNklWirJrnPjrySDoHDOoZWYy3ajgPkQNURgzkyGShwRhxogWXxVwPqI15V1lOU/kXMZUW1QJycH9se9/GDBRxVaBhJXP2J6WEUYBMwkZJZA7gmVgy/3FKSQIDAQAB
私钥:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAM+HfQO7hVU+PGxdb8GfoHujZh7SUGPnUCDeEIwo7814XowPXM2ra42SVaKsmuc+OvJIOgcM6hlZjLdqOA+RA1RGDOTIZKHBGHGiBZfFXA+ojXlXWU5T+RcxlRbVAnJwf2x738YMFHFVoGElc/YnpYRRgEzCRklkDuCZWDL/cUpJAgMBAAECgYBOjIxLbN8vIBLTu1vw7//YvESLVvRZk/RWtGaT/myhmzVCExB/wim/2Ir0OxuYegvqp17bS06SELx7sccNUUhuH2ZWOT/jGlN4RxteGVV49Fnkp2W3XtmADJw7tLS85uu6S3Zox98P2Bsv6HzRcdd9ZS28sMYyWUWaaS5Szjd5twJBAOgVrSNTEqb3xGM6FL0TkCg+szVwFlUQoDdxzXl18WTO8u8PTRlFspnBm6/5h2A7QW3trzGveCw5h3lhVSfU5hsCQQDk6gwiMM9zuPY+ver7PiYjvc4E8s2zgmSYdA9qOuPdsML00fTAwXyFtYAVhzW/VG5xqpH665Y86qhccvqBpSdrAkA4bFSsetzVBPWU3iD+msv4TM4K1tZHFgStlhhLSDZIuNts7T5kP4KdSOmNzc9wwNc2X4uxO6Sus8nQ463tQiAzAkEAvaod+4YtnFg3zqxUsW5A84Qj2n3CaWU0LAydaQr6GYiHP4lmHP8zSSWkxjGNGsW97HfDE/92L2rNrCun2xsXmQJAS6yS8W9vJw8xSsyHHBzVaLq8TCfZPfZEHKe1ussxgyCAaxRGoKwiyNBIJG22r54EYn+70IcF2YVq7QYw6GzkTA==
加密前1234Hello你好,加密后:R/H4pNUadKAur7pAMxei7iRUpYNVLdCfA2GGsN9z2MHMAGFQ7RIXgPKDfBCI0nPlMbEa+cYeU904beXvc722Sto8v5Ft7P+gJNS9ttGbRibvtOp5IrS5KaprHbvuR2VSPqkBzCHOBlrPa7MXHVXLRaJnJkF1yrQLwQmaWuGUNaQ=
解密后:1234Hello你好
八、其他摘要算法
public static void other(String data){
Console.log("md5加密前:{},加密后:{}", data, EncryptUtils.encryptByMd5(data));
Console.log("sha256加密前:{},加密后:{}", data, EncryptUtils.encryptBySha256(data));
Console.log("sm3加密前:{},加密后:{}", data, EncryptUtils.encryptBySm3(data));
}
结果
md5加密前:1234Hello你好,加密后:23995e5a0e5683f14c6025de9088b51a
sha256加密前:1234Hello你好,加密后:7409f5274ff117ac6f6db6b6cfd8159e9e6a25510e996549e2ebf437c2088bcf
sm3加密前:1234Hello你好,加密后:470f2ecd0947593b282543dc1fe88127c3aff3f9a4d51ea1b4df230b79e717ad
博主精心整理专栏,CV大法即可用,感谢您小手点一点 手动跪拜:
1- SpringBoot框架常用配置(若依),代码解读:
2- java常用工具类整理,示例演示:
3- CompletableFuture 异步编排与实际代码展示
4- XXL-JOB 详细学习,手把手带入门