700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Java加密算法—对称加密(DES AES)

Java加密算法—对称加密(DES AES)

时间:2021-12-22 04:54:57

相关推荐

Java加密算法—对称加密(DES AES)

目录

1、概述2、加密模式2.1 ECB2.2 CBC3、填充模式4、对称加密、解密实现

1、概述

对称加密就是采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,也称为单密钥加密。

比如:凯撒加密就可以认为是一种对称加密,将偏移量看作密钥,加密和解密都用的是相同的偏移量(密钥)

常见加密算法:

DES : Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美 国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。AES : Advanced Encryption Standard, 高级加密标准 .在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

特点:

加密速度快, 可以加密大文件。密文可逆, 一旦密钥文件泄漏, 就会导致数据暴露。加密后编码表找不到对应字符, 出现乱码,一般结合Base64使用。

2、加密模式

2.1 ECB

ECB : Electronic codebook, 电子密码本. 需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密。

优点 : 可以并行处理加密数据,速度快。缺点 : 同样的原文生成同样的密文, 不能很好的保护数据。

2.2 CBC

CBC : Cipher-block chaining, 密码块链接. 每个明文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有明文块。

优点 : 同样的原文生成的密文不一样。

缺点 : 串行处理数据,速度较慢。

3、填充模式

当需要按块处理的数据, 数据长度不符合块处理需求时, 按照一定的方法填充满块长的规则,分为NoPaddingPKCS5Padding

NoPadding:

不填充。在DES加密算法下, 要求原文长度必须是8byte的整数倍。在AES加密算法下, 要求原文长度必须是16byte的整数倍。

PKCS5Padding:

数据块的大小为8位, 不够就补足

注意:

默认情况下, 加密模式和填充模式为 : ECB/PKCS5Padding如果使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new IvParameterSpec(key.getBytes());

加密模式和填充模式创建模式:

AES/CBC/NoPadding (128)AES/CBC/PKCS5Padding (128)AES/ECB/NoPadding (128)AES/ECB/PKCS5Padding (128)DES/CBC/NoPadding (56)DES/CBC/PKCS5Padding (56)DES/ECB/NoPadding (56)DES/ECB/PKCS5Padding (56)

4、对称加密、解密实现

将对称加密的DES和AES进行封装处理,达到一套代码实现两种加密方式,结合了加密模式和填充模式的应用,代码可以直进行使用。。

代码实现:

public class SymmetryTest {private final static String DES = "DES";private final static String AES = "AES";/*** 设置为CBC加密模式,默认情况下ECB比CBC更高效*/private final static String CBC = "/CBC/PKCS5Padding";public static void main(String[] args) {// 对称加密 密文String input = "key=85CD019515D14B91AD942787532314FF&startTime=1629431243245&endTime=1660967243244";// DES加密算法,key的大小必须是8个字节String desKey = "12345678";// AES加密算法,key的大小必须是16个字节String aesKey = "1234567812345678";String encryptDes = encryptBySymmetry(input, desKey, SymmetryTest.DES, true);System.out.println("DES加密:" + encryptDes);String des = decryptBySymmetry(encryptDes, desKey, SymmetryTest.DES, true);System.out.println("DES解密:" + des);System.out.println("\n==============================================\n");String encryptAes = encryptBySymmetry(input, aesKey, SymmetryTest.AES);System.out.println("AES加密:" + encryptAes);String aes = decryptBySymmetry(encryptAes, aesKey, SymmetryTest.AES);System.out.println("AES解密:" + aes);}/*** 对称加密** @param input: 密文* @param key : 密钥* @param algorithm : 类型:DES、AES* @return*/public static String encryptBySymmetry(String input, String key, String algorithm) {return encryptBySymmetry(input, key, algorithm, false);}/*** 对称解密** @param input: 密文* @param key : 密钥* @param algorithm : 类型:DES、AES* @return*/public static String decryptBySymmetry(String input, String key, String algorithm) {return decryptBySymmetry(input, key, algorithm, false);}/*** 对称加密数据** @param input: 原文* @param key : 密钥* @param algorithm : 类型:DES、AES* @param cbc : CBC加密模式:同样的原文生成的密文不一样,串行进行,加密使用CBC解密也需要CBC* @return : 密文* @throws Exception*/public static String encryptBySymmetry(String input, String key, String algorithm, Boolean cbc) {try {// 根据加密类型判断key字节数checkAlgorithmAndKey(key, algorithm);// CBC模式String transformation = cbc ? algorithm + CBC : algorithm;// 获取加密对象Cipher cipher = Cipher.getInstance(transformation);// 创建加密规则// 第一个参数key的字节// 第二个参数表示加密算法SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);// ENCRYPT_MODE:加密模式// DECRYPT_MODE: 解密模式// 初始化加密模式和算法// 默认采用ECB加密:同样的原文生成同样的密文,并行进行// CBC加密:同样的原文生成的密文不一样,串行进行if (cbc) {// 使用CBC模式IvParameterSpec iv = new IvParameterSpec(key.getBytes());cipher.init(Cipher.ENCRYPT_MODE, sks, iv);} else {cipher.init(Cipher.ENCRYPT_MODE, sks);}// 加密byte[] bytes = cipher.doFinal(input.getBytes());// 输出加密后的数据return Base64.encode(bytes);} catch (Exception e) {e.printStackTrace();throw new RuntimeException("加密失败!");}}/*** 对称解密** @param input: 密文* @param key : 密钥* @param algorithm : 类型:DES、AES* @param cbc : CBC加密模式:同样的原文生成的密文不一样,串行进行,加密使用CBC解密也需要CBC* @throws Exception* @return: 原文*/public static String decryptBySymmetry(String input, String key, String algorithm, Boolean cbc) {try {// 根据加密类型判断key字节数checkAlgorithmAndKey(key, algorithm);// CBC模式String transformation = cbc ? algorithm + CBC : algorithm;// 1,获取Cipher对象Cipher cipher = Cipher.getInstance(transformation);// 指定密钥规则SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);// 默认采用ECB加密:同样的原文生成同样的密文// CBC加密:同样的原文生成的密文不一样if (cbc) {// 使用CBC模式IvParameterSpec iv = new IvParameterSpec(key.getBytes());cipher.init(Cipher.DECRYPT_MODE, sks, iv);} else {cipher.init(Cipher.DECRYPT_MODE, sks);}// 3. 解密,上面使用的base64编码,下面直接用密文byte[] bytes = cipher.doFinal(Base64.decode(input));// 因为是明文,所以直接返回return new String(bytes);} catch (Exception e) {e.printStackTrace();throw new RuntimeException("解密失败!");}}private static void checkAlgorithmAndKey(String key, String algorithm) {// 根据加密类型判断key字节数int length = key.getBytes().length;boolean typeEnable = false;if (DES.equals(algorithm)) {typeEnable = length == 8;} else if (AES.equals(algorithm)) {typeEnable = length == 16;} else {throw new RuntimeException("加密类型不存在");}if (!typeEnable) {throw new RuntimeException("加密Key错误");}}}

效果:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。