Java实现对称加密(DES,AES)快速入门示例

对称加密是使用相同的密码进行加密和解密, 对称加密实现简单,安全性相比非对称加密较弱, 常用的对称加密算法有 DES,AES以及PDE等,关于对称加密相关概念参考:
对称加密、非对称加密深度解析

本篇介绍Java的DES和AES的加密和解密, 关于PDE算法的加解密实现, 可以参考:
Java使用PBE算法进行对称加解密最简入门和示例

DES 加密和解密

在Java语言中, DES 算法使用一个密钥进行加密和解密,使用密码规范(DESKeySpec)和密钥工厂(SecretKeyFactory)生成密钥。通过Cipher类来进行加密和解密操作,使用“DES/ECB/PKCS5Padding”作为加密算法和填充模式。

DES加密示例代码:

	/**
	 * DES 对称加密
	 */
	@Test
	public void desEncrypt() throws Exception {
		String plainText = "需要加密的内容";
		String secretKey = "this is password";
		DESKeySpec desKeySpec = new DESKeySpec(secretKey.getBytes(StandardCharsets.UTF_8));
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey key = keyFactory.generateSecret(desKeySpec);

		Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, key);

		byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
		String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
		System.out.println("DES加密后的内容=" + encryptedText);
	}

DES 解密示例代码:

	
	@Test
	public void desDecrypt() throws Exception {
		String encryptedText = "HAyFHQXRKmihGtxFsrZlAJwla4FE3aqS";
		String secretKey = "this is password";
		DESKeySpec desKeySpec = new DESKeySpec(secretKey.getBytes(StandardCharsets.UTF_8));
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey key = keyFactory.generateSecret(desKeySpec);

		Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		cipher.init(Cipher.DECRYPT_MODE, key);

		byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
		String plainText = new String(decryptedBytes, StandardCharsets.UTF_8);
		System.out.println("DES解密的内容=" + plainText);
	}

这里为什么是DES/ECB/PKCS5Padding , 而不直接是 DES呢?

DES/ECB/PKCS5Padding 是一种加密算法和模式的规范,常用于对数据进行加密和解密操作。

具体来说:

  • DES(Data Encryption Standard)是一种对称加密算法,它使用相同的密钥(通常是 56 位长)进行加密和解密操作。
  • ECB(Electronic Codebook)是一种加密模式,它将输入的数据分成块,每块独立进行加密运算。
  • PKCS5Padding 是一种填充模式,它在数据块长度不足时,使用特定的填充方式进行填充,使每个数据块的长度达到指定长度。

DES/ECB/PKCS5Padding 相比其他加密算法和模式,具有以下优点和缺点:

优点:

  • 运算速度相对较快,适合对大数据流进行加密和解密操作;

  • 实现比较简单,可在多种编程语言和平台上进行实现;

  • 加密后的数据大小不会增加。

缺点:

  • ECB 模式不具备随机性和反复率,相邻数据块可能会产生相同的密文,容易受到攻击;

  • 密钥长度较短,安全性相对较低,易受到暴力破解和密码分析攻击;

使用相同密钥加密同一数据,密文总是相同,可容易地进行重放攻击和密码攻击。

因此,对于加密性能要求较高,安全要求相对较低的场景,可以选择使用 DES/ECB/PKCS5Padding 进行加密和解密操作。对于安全性要求较高的场景,应该考虑使用更加安全和可靠的加密算法和模式,比如 AES、RSA、CBC、GCM 等。

AES 加密和解密

AES 的加解密和DES很类似,直接看代码:

AES加密代码示例:

	@Test
	public void encryptAES() throws Exception {
		String plainText = "需要加密的内容";
		String secretKey = "this is password";
		SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
        String encryptedText =  Base64.getEncoder().encodeToString(encryptedBytes);
        System.out.println("AES加密后的内容=" + encryptedText);
	}

AES解密代码示例:

	@Test
	public void decryptAES() throws Exception {
		String encryptedText = "oL2b5xULTtAmfi4ujnpw/jPamo0nTNCgRC9Bo+SBz7k=";
		String secretKey = "this is password";
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
		String plainText = new String(decryptedBytes, StandardCharsets.UTF_8);
		System.out.println("AES解密的内容=" + plainText);
	}

AES(Advanced Encryption Standard)使用相同的密钥进行加密和解密操作。这个示例中使用密钥字符串构建了一个 AES 密钥规范(SecretKeySpec),并通过 Cipher 类来进行加密和解密操作,使用 “AES/ECB/PKCS5Padding” 作为加密算法和填充模式。

需要注意的是,AES 是一个块密码算法,不同于 DES 等分块密码,它支持不同的密钥长度,如 AES-128、AES-192 和 AES-256。

在实际应用中,为了保证安全性,密钥应该足够长,同时需要确保密钥的安全生成、存储和传输。

Java 8 找不到 javax.crypto.spec.SecretKeySpec问题解决

在Java 11 和Java 17版本中,上面示例运行正常,但是在Java 8 中会提示找不到 javax.crypto.spec.SecretKeySpec,在及基于Eclipse 开发中, 虽然import 了SecretKeySpec , 但是会提示找不到这个类:

The import javax.crypto.spec.SecretKeySpec cannot be resolved

这里需要下载jce的扩展包,下载地址:
https://www.oracle.com/java/technologies/javase-jce8-downloads.html

下载后解压,
在这里插入图片描述

将 local_policy.jar 和US_export_policy.jar 放入JRE 的security目录中,比如C:\Program Files\Java\jdk1.8.0_361\jre\lib\security\policy\unlimited, 覆盖该目录下的同名文件:
在这里插入图片描述

之后在 Eclipse 的项目中导入这两个文件。

在线代码



猜你喜欢

转载自blog.csdn.net/oscar999/article/details/132254062