【Java工具类】对称加密之整合AES、DES算法加解密工具类
程序员文章站
2022-03-12 21:39:28
...
- 对称加密算法只是为了区分非对称加密算法。特点就是
加密是加密解密使用相同的**
,而非对称加密加密和解密时使用的**不一样
。- 对称加密的**交换时可以使用非对称加密,这有效保护**的安全。
- 非对称加密加密和解***不同,安全性高,但加解密的速度很慢,不适合对大数据加密。而对称加密加密速度快,因此混合使用最好。
常用的对称加密算法有:AES和DES.
- DES:
比较老的算法
,一共有三个参数入口(原文,**,加密模式)。而3DES只是DES的一种模式,是以DES为基础更安全的变形,对数据进行了三次加密,也是被指定为AES的过渡算法。 -
AES:高级加密标准,新一代标准,
加密速度更快,安全性更高(优先选择)
import org.junit.Test;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
public class SymmetricEncryptionUtil {
private static final String AES = "AES";
private static final String DES = "DES";
/**
* AES**
*/
private static final String AES_KEY = "FFC22E80F61AB7295C02493856B4C520";
/**
* AES模式
*/
private static final String AES_MODE = "AES/ECB/PKCS5Padding";
/**
* DES**: 加解密用到的秘钥-getBytes().length即字节的长度必须大于等于8,否则报异常java.security.InvalidKeyException: Wrong key size
*/
private static final String DES_KEY = "*%#@()^&";
/**
* DES模式
* "AES/ECB/PKCS5Padding"在加密和解密时必须相同,可以直接写”AES”,这样就是使用默认模式分别的意思为:AES是加密算法,ECB是工作模式,PKCS5Padding是填充方式。
*/
private static final String DES_MODE = "DES/ECB/PKCS5Padding";
/**
* 使用AES对字符串加密
*
* @param str utf8编码的字符串
* @param key **(16字节)
* @return 加密结果
* @throws Exception
*/
public static String aesEncrypt(String str, String key) throws Exception {
if (str == null || key == null) {
return null;
}
//AES/ECB/PKCS5Padding在加密和解密时必须相同
Cipher cipher = Cipher.getInstance(AES_MODE);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES));
byte[] bytes = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));
//使用base64编码
return Base64.getEncoder().encodeToString(bytes);
}
/**
* 使用AES对数据解密
*
* @param base64Encoder base64编码后的字符串
* @param key **(16字节)
* @return 解密结果
* @throws Exception
*/
public static String aesDecrypt(String base64Encoder, String key) throws Exception {
if (base64Encoder == null || key == null) {
return null;
}
SecureRandom random = new SecureRandom();
Cipher cipher = Cipher.getInstance(AES_MODE);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES), random);
//使用base64解码
byte[] base64DecoderByte = Base64.getDecoder().decode(base64Encoder);
return new String(cipher.doFinal(base64DecoderByte), StandardCharsets.UTF_8);
}
/**
* 使用DES对字符串加密
*
* @param str utf8编码的字符串
* @param key **(56位,7字节)
* @return 加密结果
* @throws Exception
*/
public static String desEncrypt(String str, String key) throws Exception {
if (str == null || key == null) {
return null;
}
SecureRandom random = new SecureRandom();
Cipher cipher = Cipher.getInstance(DES_MODE);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), DES), random);
byte[] bytes = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));
//使用base64编码
return Base64.getEncoder().encodeToString(bytes);
}
/**
* 使用DES对数据解密
*
* @param base64Encoder base64编码后的字符串
* @param key **(16字节)
* @return 解密结果
* @throws Exception
*/
public static String desDecrypt(String base64Encoder, String key) throws Exception {
if (base64Encoder == null || key == null) {
return null;
}
Cipher cipher = Cipher.getInstance(DES_MODE);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), DES));
//使用base64解码
byte[] base64DecoderByte = Base64.getDecoder().decode(base64Encoder);
return new String(cipher.doFinal(base64DecoderByte), StandardCharsets.UTF_8);
}
/**
* 测试AES算法
*
* @throws Exception
*/
@Test
public void main1() throws Exception {
String str = "你好,张三!";
System.out.println("原文:" + str);
System.out.println("**:" + AES_KEY);
String aesEncrypt = aesEncrypt(str, AES_KEY);
System.out.println("加密后:" + aesEncrypt);
String aesDecrypt = aesDecrypt(aesEncrypt, AES_KEY);
System.out.println("解密后:" + aesDecrypt);
}
/**
* 测试DES算法
*
* @throws Exception
*/
@Test
public void main2() throws Exception {
String str = "你好,张三!";
System.out.println("原文:" + str);
System.out.println("**:" + DES_KEY);
String aesEncrypt = desEncrypt(str, DES_KEY);
System.out.println("加密后:" + aesEncrypt);
String aesDecrypt = desDecrypt(aesEncrypt, DES_KEY);
System.out.println("解密后:" + aesDecrypt);
}
}
执行结果
```java
//main1
原文:你好,张三!
**:FFC22E80F61AB7295C02493856B4C520
加密后:Vlm7AY5VxhiOc5QSZe5Szga2oN2+AMpMDyHU9tYktFw=
解密后:你好,张三!
//main2
原文:你好,张三!
**:*%#@()^&
加密后:STDcjuovhcYOwV/tFmrvPH25wWw6o48M
解密后:你好,张三!
AES算法的所有参数都是字节码的(包括**)。因此字符串字符需要转换成字节码后进行加密
- 参数:
”AES/ECB/PKCS5Padding”
在加密和解密时必须相同,可以直接写”AES”,这样就是使用默认模式。分别的意思为:AES是加密算法
,ECB是工作模式
,PKCS5Padding是填充方式
。
AES是分组加密算法,也称块加密。每一组16字节。这样明文就会分成多块。当有一块不足16字节时就会进行填充。一共有四种工作模式:
- ECB 电子密码本模式:相同的明文块产生相同的密文块,容易并行运算,但也可能对明文进行攻击。
- CBC 加密分组链接模式:一块明文加密后和上一块密文进行链接,不利于并行,但安全性比ECB好,是SSL,IPSec的标准。
- CFB 加密反馈模式:将上一次密文与**运算,再加密。隐藏明文模式,不利于并行,误差传递。
- OFB 输出反馈模式:将上一次处理过的**与**运算,再加密。隐藏明文模式,不利于并行,有可能明文攻击,误差传递。
PKCS5Padding的填充方式是差多少字节就填数字多少;刚好每一不足16字节时,那么就会加一组填充为16.还有其他填充模式【Nopadding,ISO10126Padding】(不影响算法,加密解密时一致就行)。
上一篇: php中截取字符串的方法有哪些