【Java】对称加密DES和AES

    技术2026-06-10  11

    文章目录

    前言1、 核心原理2、 特点3、 常见的加密算法4、 加密模式5、 填充模式6、DES加密实现7、AES加密实现

    前言

    对称加密,加密和解密用的同一个秘钥,也叫单密钥加密。

    1、 核心原理

    流加密和块加密

    流加密(序列密码):是对信息中的每一个元素(一个字母或者一个比特)作为基础的处理单元进行加密。 例如:1234678 先加密1再加密2再见3,以此类推。块加密(分组密码):是先对信息进行分块,在对每一块分别加密。 例如:1234678 先分块 分为 1234 和 5678 再先加密1234 再加密5678。

    2、 特点

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

    3、 常见的加密算法

    DES加解密,key必须8个字节 AES加解密,key必须16个字节

    4、 加密模式

    加密模式:ECB、CBC

    ECB Electronic code book 电子密码本,需要加密的消息按照块密码的大小被分为数个块,并对每个块进行独立加密。 优点:可以并行处理数据 缺点:同样的原文生成同样的密文,不能很好的保护数据, 同时加密,原文是一样的,加密出来的密文也是一样的。CBC Cipher-block chaining 密码块连接,每个明文块先和前一个密文块进行异或后,在进行加密。这样每个密文块都依赖了他前面的所有明文块。 优点:同样的原文生成不一样的密文 缺点:串行处理数据,加密慢 CBC模式需要指定iv变量

    5、 填充模式

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

    NoPadding 1、不填充 2、在DES加密算法下,要求原文长度必须是8Byte的整数倍。 3、在AES加密算法下,要求原文长度必须是16Byte的整数倍.PKCS5Padding 数据块的大小为8位不够就补充,先分块,最后一个可能够8位,也不够8位,不够时就补全。

    6、DES加密实现

    package com.lh.basecryptology.desaes; import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class DesDemo { public static void main(String[] args) throws Exception { // 原文 String text = "十里洋场,遍地黄金"; // 密钥 如果用Des加密密钥必须8位 String key = "12345678"; // 算法 // DES 默认是 DES/ECB/PKCS5Padding String transformation = "DES"; // DES/ECB/PKCS5Padding URi9FEpJ67KLV+LYiQjmRZ+dulH/ltTO5ejvMir6dwo= // String transformation = "DES/ECB/PKCS5Padding"; System.out.println("==========" + transformation); // 加密类型 ECB/PKCS5Padding String algorithm = "DES"; String encrypt = encryptECB(text, key, transformation, algorithm); System.out.println("密文ECB:" + encrypt); String decrypt = decryptECB(encrypt, key, transformation, algorithm); System.out.println("原文ECB:" + decrypt); // 加密类型 ECB/PKCS5Padding transformation = "DES/ECB/NoPadding"; System.out.println("==========" + transformation); String encryptNoPadding = encryptNoPadding(text, key, transformation, algorithm); System.out.println("密文ECBNoPadding:" + encryptNoPadding); String decryptNoPadding = decryptECB(encrypt, key, transformation, algorithm); System.out.println("原文ECBNoPadding:" + decryptNoPadding); // 加密模式为CBC时需要指定iv向量 transformation = "DES/CBC/PKCS5Padding"; System.out.println("==========" + transformation); String encryptCBC = encryptCBC(text, key, "DES/CBC/PKCS5Padding", algorithm); System.out.println("密文CBC:" + encryptCBC); String decryptCBC = decryptCBC(encryptCBC, key, "DES/CBC/PKCS5Padding", algorithm); System.out.println("原文CBC:" + decryptCBC); } /** * 使用DES加密 * * @param text 原文 * @param key 密钥 * @param transformation 加密算法 * @param algorithm 加密类型 * @throws Exception */ private static String encryptECB(String text, String key, String transformation, String algorithm) throws Exception { //创建加密对象 transformation加密算法 Cipher cipher = Cipher.getInstance(transformation); //创建加密规则 第一个参数key字节 第二个参数表示加密类型 SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm); // 进行加密初始化 第一个参数表示模式 加密模式和解密模式 第二个参数表示加密规则 cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); // 调用加密方法 // 参数是原文的字节数组 byte[] bytes = cipher.doFinal(text.getBytes()); /*for (byte aByte : bytes) { System.out.println(aByte); } // 如果直接打印密文会出现乱码,是因为在编码表里面找不到对应的字符,ascii码只有正数 System.out.println(new String(bytes));*/ // 使用base64 转码 return Base64.encode(bytes); } /** * 解密 * * @param encrypt 密文 * @param key 秘钥 * @param transformation 加密算法 * @param algorithm 机密类型 * @return 解密后的内容 */ private static String decryptECB(String encrypt, String key, String transformation, String algorithm) throws Exception { byte[] decode = Base64.decode(encrypt); Cipher cipher = Cipher.getInstance(transformation); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm); // 进行加密初始化 第一个参数表示模式 加密模式和解密模式 第二个参数表示加密规则 cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); // 调用解密方法 byte[] bytes = cipher.doFinal(decode); return new String(bytes); } /** * 使用DES加密 * * @param text 原文 * @param key 密钥 * @param transformation 加密算法 * @param algorithm 加密类型 * @throws Exception */ private static String encryptCBC(String text, String key, String transformation, String algorithm) throws Exception { //创建加密对象 transformation加密算法 Cipher cipher = Cipher.getInstance(transformation); //创建加密规则 第一个参数key字节 第二个参数表示加密类型 SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm); // 创建IV向量 在使用iv向量是 iv的字节也必须要8个字节 IvParameterSpec iv = new IvParameterSpec(key.getBytes()); // 进行加密初始化 第一个参数表示模式 加密模式和解密模式 第二个参数表示加密规则 cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, iv); // 调用加密方法 // 参数是原文的字节数组 byte[] bytes = cipher.doFinal(text.getBytes()); /*for (byte aByte : bytes) { System.out.println(aByte); } // 如果直接打印密文会出现乱码,是因为在编码表里面找不到对应的字符,ascii码只有正数 System.out.println(new String(bytes));*/ // 使用base64 转码 return Base64.encode(bytes); } /** * 解密 * * @param encrypt 密文 * @param key 秘钥 * @param transformation 加密算法 * @param algorithm 机密类型 * @return 解密后的内容 */ private static String decryptCBC(String encrypt, String key, String transformation, String algorithm) throws Exception { byte[] decode = Base64.decode(encrypt); Cipher cipher = Cipher.getInstance(transformation); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm); // 创建IV向量 IvParameterSpec iv = new IvParameterSpec(key.getBytes()); // 进行加密初始化 第一个参数表示模式 加密模式和解密模式 第二个参数表示加密规则 cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv); // 调用解密方法 byte[] bytes = cipher.doFinal(decode); return new String(bytes); } /** * 使用DES加密 * * @param text 原文 * @param key 密钥 * @param transformation 加密算法 * @param algorithm 加密类型 * @throws Exception */ private static String encryptNoPadding(String text, String key, String transformation, String algorithm) throws Exception { //创建加密对象 transformation加密算法 Cipher cipher = Cipher.getInstance(transformation); //创建加密规则 第一个参数key字节 第二个参数表示加密类型 SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm); // 进行加密初始化 第一个参数表示模式 加密模式和解密模式 第二个参数表示加密规则 cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); // 调用加密方法 // 参数是原文的字节数组 return Base64.encode(cipher.doFinal(addZero(text.getBytes()))); } /** * NoPadding 补0 * 在DES加密算法下,要求原文长度必须是8Byte的整数倍。 * 在AES加密算法下,要求原文长度必须是16Byte的整数倍. * * @param data 数组 * @return 补0之后 */ private static byte[] addZero(byte[] data) { byte[] dataByte = data; if (data.length % 8 != 0) { byte[] temp = new byte[8 - data.length % 8]; dataByte = byteMerger(data, temp); } return dataByte; } /** * java 合并两个byte数组 * System.arraycopy()方法 * * @param bt1 数组1 * @param bt2 数组2 * @return 合并结果 */ private static byte[] byteMerger(byte[] bt1, byte[] bt2) { byte[] bt3 = new byte[bt1.length + bt2.length]; System.arraycopy(bt1, 0, bt3, 0, bt1.length); System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length); return bt3; } }

    7、AES加密实现

    package com.lh.basecryptology.desaes; import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class AesDemo { public static void main(String[] args) throws Exception { // 原文 String text = "十里洋场,遍地黄金"; // 密钥 如果用AES加密密钥必须16个字节 String key = "1234567812345678"; // 算法 String transformation = "AES"; // 加密类型 String algorithm = "AES"; String encrypt = encryptAES(text, key, transformation, algorithm); System.out.println("密文:" + encrypt); String decrypt = decryptAES(encrypt, key, transformation, algorithm); System.out.println("原文:" + decrypt); } /** * 解密 * * @param encrypt 密文 * @param key 秘钥 * @param transformation 加密算法 * @param algorithm 机密类型 * @return 解密后的内容 */ private static String decryptAES(String encrypt, String key, String transformation, String algorithm) throws Exception { byte[] decode = Base64.decode(encrypt); Cipher cipher = Cipher.getInstance(transformation); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm); // 进行AES加密初始化 第一个参数表示模式 加密模式和解密模式 第二个参数表示加密规则 cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); // 调用解密方法 byte[] bytes = cipher.doFinal(decode); return new String(bytes); } /** * 使用AES加密 * * @param text 原文 * @param key 密钥 * @param transformation 加密算法 * @param algorithm 加密类型 * @throws Exception */ private static String encryptAES(String text, String key, String transformation, String algorithm) throws Exception { //创建加密对象 transformation加密算法 Cipher cipher = Cipher.getInstance(transformation); //创建加密规则 第一个参数key字节 第二个参数表示加密类型 SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm); // 进行AES加密初始化 第一个参数表示模式 加密模式和解密模式 第二个参数表示加密规则 cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); // 调用加密方法 // 参数是原文的字节数组 byte[] bytes = cipher.doFinal(text.getBytes()); /*for (byte aByte : bytes) { System.out.println(aByte); } // 如果直接打印密文会出现乱码,是因为在编码表里面找不到对应的字符,ascii码只有正数 System.out.println(new String(bytes));*/ // 使用base64 转码 return Base64.encode(bytes); } }
    Processed: 0.009, SQL: 9