<>场景

调用第三方接口返回数据需要AES/ECB/PKCS5Padding解密。

<>导入的包
import org.apache.commons.codec.binary.Hex; import org.slf4j.Logger; import org
.slf4j.LoggerFactory; import sun.misc.BASE64Decoder; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.
crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java
.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException;
import java.util.Base64;
<>代码片段
public class AESUtil { private static Logger log = LoggerFactory.getLogger(
AESUtil.class); /** * 密钥算法 */ private static final String ALGORITHM = "AES";
/** * 加解密算法/工作模式/填充方式 */ private static final String ALGORITHM_STR =
"AES/ECB/PKCS5Padding"; /** * SecretKeySpec类是KeySpec接口的实现类,用于构建秘密密钥规范 */ private
SecretKeySpec key; public AESUtil(String hexKey) { key = new SecretKeySpec(
hexKey.getBytes(), ALGORITHM); } /** * AES解密 * @param base64Data * @return *
@throws Exception */ public String decryptData(String base64Data) throws
Exception{ Cipher cipher = Cipher.getInstance(ALGORITHM_STR); cipher.init(Cipher
.DECRYPT_MODE, key); return new String(cipher.doFinal(new BASE64Decoder().
decodeBuffer(base64Data))); } /** * 获取密钥 * @return * @throws
NoSuchAlgorithmException */ public static String initKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); //192,256
keyGenerator.init(128); SecretKey secretKey = keyGenerator.generateKey(); return
Base64.getEncoder().encodeToString(secretKey.getEncoded()); } /** *
AES+BASE64加密 * 加密方法 * 与 解密方法 {@link #decrypt} 配套使用 * @param data 要加密的数据 *
@param key 加密所使用的密钥 * @return 加密后的数据 * @throws Exception */ public static String
encrypt(String data, String key) throws Exception { byte[] keyBytes = Base64.
getDecoder().decode(key); SecretKey secretKey = new SecretKeySpec(keyBytes,
"AES"); Cipher decryptionCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = KeyGenerator.getInstance("AES").generateKey().getEncoded();
IvParameterSpec ivSpec = new IvParameterSpec(iv); decryptionCipher.init(Cipher.
ENCRYPT_MODE, secretKey , ivSpec ); byte[] cipherText = decryptionCipher.doFinal
(data.getBytes()); byte[] iv_cipher = new byte[iv.length + cipherText.length];
int i = 0 ; for (; i < iv.length; i++) { iv_cipher[i] = iv[i]; } for (int j = 0;
j< cipherText.length; j++) { iv_cipher[(i + j)] = cipherText[j]; } return
Base64.getEncoder().encodeToString(iv_cipher); } /** * AES+BASE64解密 * 与
加密方法{@link #encrypt} 配套使用 * @param data 要解密的数据 * @param key 解密所使用的密钥 * @return
解密后的数据, 即源数据 * @throws Exception */ public static String decrypt(String data,
String key) throws Exception { byte[] keyBytes = Base64.getDecoder().decode(key)
; SecretKey keySpec = new SecretKeySpec(keyBytes, "AES"); Cipher
decryptionCipher= Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] iv_cipher =
Base64.getDecoder().decode(data); byte[] iv = new byte[16]; byte[] cipher = new
byte[iv_cipher.length - 16]; int i = 0; int j = 0; for (; i < 16; i++) { iv[i] =
iv_cipher[i]; } for (; i < iv_cipher.length; i++) { cipher[j] = iv_cipher[i]; j
++; } IvParameterSpec ivSpec = new IvParameterSpec(iv); decryptionCipher.init(2,
keySpec, ivSpec); return new String(decryptionCipher.doFinal(cipher), "UTF-8");
} /** * 加密方法 * 与 解密方法{@link #decryptWithHex} 配套使用 *
将不符合要求的密钥处理为16位的ASCII编码的数组,使用AES加密, * 将加密的字节数组转为十六进制字符数组,然后将其转换为utf-8字符串。 *
@param preString 待加密的字符串 * @param strKey 密钥 * @return */ public static String
encryptWithHex(String preString, String strKey) { try { SecretKey key =
generateMySQLAESKey(strKey,"ASCII"); Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key); byte[] cleartext = preString.getBytes(
"UTF-8"); byte[] ciphertextBytes = cipher.doFinal(cleartext); return new String(
Hex.encodeHex(ciphertextBytes)); } catch (Exception e) { log.error(
"{}字符串通过AES密钥{}加密异常",preString, strKey, e); } return null; } /** * 解密方法 * 与
加密方法{@link #encryptWithHex} 配套使用 * @param preString 待加密的字符串 * @param strKey 密钥
*/ public static String decryptWithHex(String preString, String strKey){ try {
SecretKey key = generateMySQLAESKey(strKey,"ASCII"); Cipher cipher = Cipher.
getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] cleartext =
Hex.decodeHex(preString.toCharArray()); byte[] ciphertextBytes = cipher.doFinal(
cleartext); return new String(ciphertextBytes, "UTF-8"); } catch (Exception e) {
log.error("{}字符串通过AES密钥{}解密异常",preString, strKey, e); } return null; } /** *
将不符合要求的密钥处理为16位的ASCII编码的字节数组 * 数据库AES算法也是如此处理的 */ private static SecretKeySpec
generateMySQLAESKey(final String key, final String encoding) { try { final byte[
] finalKey = new byte[16]; int i = 0; for(byte b : key.getBytes(encoding)){
finalKey[i++%16] ^= b; } return new SecretKeySpec(finalKey, "AES"); } catch(
UnsupportedEncodingException e) { throw new RuntimeException(e); } } }
<>总结

如有其他更好的方法或者想法,可以留言或联系分享,大家互相学习进步。

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信