Java实现AES CBC PKCS7Padding加解密

版权申诉
0 下载量 106 浏览量 更新于2024-08-07 1 收藏 17KB DOCX 举报
本文档提供了一种在Java中实现AES(高级加密标准)CBC(密码块链接)模式并使用PKCS7Padding填充的方案。它介绍了解决Java原生不支持PKCS7Padding问题的方法,即引入BouncyCastle库作为安全提供者。 ### Java实现AES CBC PKCS7Padding加解密 #### 问题背景 在前后端通信中,为了数据安全,通常会采用加密技术。Java标准库中内置了AES加密,但仅支持NoPadding和PKCS5Padding填充方式。然而,前端可能使用如crypto-js这样的库,该库支持PKCS7Padding。为保持前后端加密的一致性,需要在Java端也实现PKCS7Padding。 #### 引入BouncyCastle依赖 解决Java不支持PKCS7Padding的问题,可以引入BouncyCastle库,一个强大的密码学API。在Maven项目中,可以通过以下依赖添加BouncyCastle: ```xml <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk16</artifactId> <version>1.46</version> </dependency> ``` 注意:这个版本号可能会随着BouncyCastle的更新而变化,建议检查最新的稳定版本。 #### 完整代码示例 以下是使用BouncyCastle实现AES CBC PKCS7Padding加解密的Java代码: ```java package com.hzjd.miniapp.util; import java.security.Security; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.bouncycastle.jce.provider.BouncyCastleProvider; import com.sun.istack.internal.NotNull; public class AESUtil { private static final String CHARSET_NAME = "UTF-8"; private static final String AES_NAME = "AES"; public static final String ALGORITHM = "AES/CBC/PKCS7Padding"; private static final String KEY = "1"; // 示例密钥,实际应用中应使用更复杂且随机的密钥 static { Security.addProvider(new BouncyCastleProvider()); } // 加密方法 public static String encrypt(@NotNull String content, String key) throws Exception { if (StringUtils.isBlank(content) || StringUtils.isBlank(key)) { throw new IllegalArgumentException("Content or key cannot be empty"); } SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(CHARSET_NAME), AES_NAME); AlgorithmParameterSpec ivSpec = new IvParameterSpec(KEY.getBytes(CHARSET_NAME)); Cipher cipher = Cipher.getInstance(ALGORITHM, BouncyCastleProvider.PROVIDER_NAME); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec); byte[] encryptedBytes = cipher.doFinal(content.getBytes(CHARSET_NAME)); return Base64.encodeBase64String(encryptedBytes); } // 解密方法 public static String decrypt(@NotNull String encryptedContent, String key) throws Exception { if (StringUtils.isBlank(encryptedContent) || StringUtils.isBlank(key)) { throw new IllegalArgumentException("Encrypted content or key cannot be empty"); } SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(CHARSET_NAME), AES_NAME); AlgorithmParameterSpec ivSpec = new IvParameterSpec(KEY.getBytes(CHARSET_NAME)); Cipher cipher = Cipher.getInstance(ALGORITHM, BouncyCastleProvider.PROVIDER_NAME); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec); byte[] decryptedBytes = cipher.doFinal(Base64.decodeBase64(encryptedContent)); return new String(decryptedBytes, CHARSET_NAME); } } ``` 在以上代码中: - `encrypt` 方法接收待加密的字符串和密钥,返回加密后的Base64编码字符串。 - `decrypt` 方法接收已加密的Base64编码字符串和密钥,返回解密后的原始字符串。 #### 使用注意事项 - 密钥(KEY)必须与加密和解密过程中保持一致。 - 实际应用中,密钥应足够复杂,建议使用128位或256位的随机生成密钥。 - 由于CBC模式需要初始化向量(IV),这里的IV与密钥相同(KEY),在实际应用中,IV应该与密钥分开管理,且在前后端之间安全地传输。 - 加密和解密过程中的字符编码应保持一致,这里使用的是UTF-8。 - 使用BouncyCastle库时,需确保已正确添加依赖,并在程序启动时注册为安全提供者。 通过这种方式,Java后端可以与前端使用相同的加密策略,实现PKCS7Padding,从而确保数据在传输过程中的安全性。