aes 加密 java_AES 加密工具(Java版本)

本文档提供了一个使用AES加密算法的Java工具类,包括16位和32位秘钥的加密解密方法。示例代码详细展示了如何进行加解密操作,同时提到了使用32位秘钥时可能遇到的非法秘钥大小问题及其解决方案。
摘要由CSDN通过智能技术生成

AES 加密

在日常工作中,经常会用到加密算法,这里我们记录下这个加密工具的使用。 直接看到代码吧:

以下是 16 长度的秘钥:

package com.topinfo.ci.netty.utils;

import java.security.SecureRandom;

import javax.crypto.Cipher;

import javax.crypto.KeyGenerator;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

/**

*@Description: AES加密和解密工具类

*@Author:杨攀

*@Since:2019年9月16日上午11:29:35

*/

public class AESUtil {

// AES secretKey length (must be 16 bytes)

public static final String secretKey = "TAZWSXEDCRFVTGBG";

// 字符串编码

private static final String KEY_CHARSET = "UTF-8";

// 算法方式

private static final String KEY_ALGORITHM = "AES";

// 算法/模式/填充

private static final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS5Padding";

// 私钥大小128/192/256(bits)位 即:16/24/32bytes,暂时使用128,如果扩大需要更换java/jre里面的jar包

private static final Integer PRIVATE_KEY_SIZE_BIT = 128;

private static final Integer PRIVATE_KEY_SIZE_BYTE = 16;

/**

*@Description: 加密

*@Author:杨攀

*@Since: 2019年9月17日上午10:17:18

*@param plainText 明文:要加密的内容

*@return 密文:加密后的内容,如有异常返回空串:""

*/

public static String encrypt(String plainText) {

return encrypt(secretKey, plainText);

}

/**

*@Description: 加密

*@Author:杨攀

*@Since: 2019年9月12日下午7:09:31

* @param secretKey 密钥:加密的规则 16位

* @param plainText 明文:要加密的内容

* @return cipherText 密文:加密后的内容,如有异常返回空串:""

*/

public static String encrypt(String secretKey, String plainText) {

if (secretKey.length() != PRIVATE_KEY_SIZE_BYTE) {

throw new RuntimeException("AESUtil:Invalid AES secretKey length (must be 16 bytes)");

}

// 密文字符串

String cipherText = "";

try {

// 加密模式初始化参数

Cipher cipher = initParam(secretKey, Cipher.ENCRYPT_MODE);

// 获取加密内容的字节数组

byte[] bytePlainText = plainText.getBytes(KEY_CHARSET);

// 执行加密

byte[] byteCipherText = cipher.doFinal(bytePlainText);

cipherText = Base64.encodeBase64String(byteCipherText);

} catch (Exception e) {

throw new RuntimeException("AESUtil:encrypt fail!", e);

}

return cipherText;

}

/**

*@Description: 解密

*@Author:杨攀

*@Since: 2019年9月17日上午10:18:19

*@param cipherText 密文:加密后的内容,即需要解密的内容

*@return 明文:解密后的内容即加密前的内容,如有异常返回空串:""

*/

public static String decrypt( String cipherText) {

return decrypt(secretKey, cipherText);

}

/**

*@Description: 解密

*@Author:杨攀

*@Since: 2019年9月12日下午7:10:06

* @param secretKey 密钥:加密的规则 16位

* @param cipherText 密文:加密后的内容,即需要解密的内容

* @return plainText 明文:解密后的内容即加密前的内容,如有异常返回空串:""

*@return

*/

public static String decrypt(String secretKey, String cipherText) {

if (secretKey.length() != PRIVATE_KEY_SIZE_BYTE) {

throw new RuntimeException("AESUtil:Invalid AES secretKey length (must be 16 bytes)");

}

// 明文字符串

String plainText = "";

try {

Cipher cipher = initParam(secretKey, Cipher.DECRYPT_MODE);

// 将加密并编码后的内容解码成字节数组

byte[] byteCipherText = Base64.decodeBase64(cipherText);

// 解密

byte[] bytePlainText = cipher.doFinal(byteCipherText);

plainText = new String(bytePlainText, KEY_CHARSET);

} catch (Exception e) {

throw new RuntimeException("AESUtil:decrypt fail!", e);

}

return plainText;

}

/**

* 初始化参数

* @param secretKey

* 密钥:加密的规则 16位

* @param mode

* 加密模式:加密or解密

*/

public static Cipher initParam(String secretKey, int mode) {

try {

// 防止Linux下生成随机key

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

secureRandom.setSeed(secretKey.getBytes());

// 获取key生成器

KeyGenerator keygen = KeyGenerator.getInstance(KEY_ALGORITHM);

keygen.init(PRIVATE_KEY_SIZE_BIT, secureRandom);

// 获得原始对称密钥的字节数组

byte[] raw = secretKey.getBytes();

// 根据字节数组生成AES内部密钥

SecretKeySpec key = new SecretKeySpec(raw, KEY_ALGORITHM);

// 根据指定算法"AES/CBC/PKCS5Padding"实例化密码器

Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);

IvParameterSpec iv = new IvParameterSpec(secretKey.getBytes());

// 初始化AES密码器

cipher.init(mode, key, iv);

return cipher;

} catch (Exception e) {

throw new RuntimeException("AESUtil:initParam fail!", e);

}

}

public static void main(String[] args) {

long s = System.currentTimeMillis();

String text = "xxxxx";

String encryptMsg = encrypt(secretKey, text);

System.out.println("密文为:" + encryptMsg);

long e = System.currentTimeMillis();

System.out.println(e-s);

String decryptMsg = decrypt(secretKey, encryptMsg);

System.out.println("明文为:" + decryptMsg);

long d = System.currentTimeMillis();

System.out.println(d-e);

}

}

以下是 32 位秘钥的模式及添加了偏移量

package com.topinfo.ci.netty.utils;

import java.security.SecureRandom;

import javax.crypto.Cipher;

import javax.crypto.KeyGenerator;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

/**

*@Description: AES加密和解密工具类

*@Author:杨攀

*@Since:2019年9月16日上午11:29:35

*/

public class AESUtil32 {

// AES secretKey length (must be 32 bytes)

public static final String secretKey = "8fd2e257a128435b8b6574e5753d825d";

// 字符串编码

private static final String KEY_CHARSET = "UTF-8";

// 算法方式

private static final String KEY_ALGORITHM = "AES";

// 算法/模式/填充

private static final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS5Padding";

// 私钥大小128/192/256(bits)位 即:16/24/32bytes,暂时使用256,如果扩大需要更换java/jre里面的jar包

private static final Integer PRIVATE_KEY_SIZE_BIT = 256;

private static final Integer PRIVATE_KEY_SIZE_BYTE = 32;

// 偏移量,可自行修改

private static final String VI = "zGrVju3LPhyhiJR8";

/**

*@Description: 加密

*@Author:杨攀

*@Since: 2019年9月17日上午10:17:18

*@param plainText 明文:要加密的内容

*@return 密文:加密后的内容,如有异常返回空串:""

*/

public static String encrypt(String plainText) {

return encrypt(secretKey, plainText);

}

/**

*@Description: 加密

*@Author:杨攀

*@Since: 2019年9月12日下午7:09:31

* @param secretKey 密钥:加密的规则 16位

* @param plainText 明文:要加密的内容

* @return cipherText 密文:加密后的内容,如有异常返回空串:""

*/

public static String encrypt(String secretKey, String plainText) {

if (secretKey.length() != PRIVATE_KEY_SIZE_BYTE) {

throw new RuntimeException("AESUtil:Invalid AES secretKey length (must be 16 bytes)");

}

// 密文字符串

String cipherText = "";

try {

// 加密模式初始化参数

Cipher cipher = initParam(secretKey, Cipher.ENCRYPT_MODE);

// 获取加密内容的字节数组

byte[] bytePlainText = plainText.getBytes(KEY_CHARSET);

// 执行加密

byte[] byteCipherText = cipher.doFinal(bytePlainText);

cipherText = Base64.encodeBase64String(byteCipherText);

} catch (Exception e) {

throw new RuntimeException("AESUtil:encrypt fail!", e);

}

return cipherText;

}

/**

*@Description: 解密

*@Author:杨攀

*@Since: 2019年9月17日上午10:18:19

*@param cipherText 密文:加密后的内容,即需要解密的内容

*@return 明文:解密后的内容即加密前的内容,如有异常返回空串:""

*/

public static String decrypt( String cipherText) {

return decrypt(secretKey, cipherText);

}

/**

*@Description: 解密

*@Author:杨攀

*@Since: 2019年9月12日下午7:10:06

* @param secretKey 密钥:加密的规则 16位

* @param cipherText 密文:加密后的内容,即需要解密的内容

* @return plainText 明文:解密后的内容即加密前的内容,如有异常返回空串:""

*@return

*/

public static String decrypt(String secretKey, String cipherText) {

if (secretKey.length() != PRIVATE_KEY_SIZE_BYTE) {

throw new RuntimeException("AESUtil:Invalid AES secretKey length (must be 16 bytes)");

}

// 明文字符串

String plainText = "";

try {

Cipher cipher = initParam(secretKey, Cipher.DECRYPT_MODE);

// 将加密并编码后的内容解码成字节数组

byte[] byteCipherText = Base64.decodeBase64(cipherText);

// 解密

byte[] bytePlainText = cipher.doFinal(byteCipherText);

plainText = new String(bytePlainText, KEY_CHARSET);

} catch (Exception e) {

throw new RuntimeException("AESUtil:decrypt fail!", e);

}

return plainText;

}

/**

* 初始化参数

* @param secretKey

* 密钥:加密的规则 16位

* @param mode

* 加密模式:加密or解密

*/

public static Cipher initParam(String secretKey, int mode) {

try {

// 防止Linux下生成随机key

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

secureRandom.setSeed(secretKey.getBytes());

// 获取key生成器

KeyGenerator keygen = KeyGenerator.getInstance(KEY_ALGORITHM);

keygen.init(PRIVATE_KEY_SIZE_BIT, secureRandom);

// 获得原始对称密钥的字节数组

byte[] raw = secretKey.getBytes();

// 根据字节数组生成AES内部密钥

SecretKeySpec key = new SecretKeySpec(raw, KEY_ALGORITHM);

// 根据指定算法"AES/CBC/PKCS5Padding"实例化密码器

Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);

IvParameterSpec iv = new IvParameterSpec(VI.getBytes());

// 初始化AES密码器

cipher.init(mode, key, iv);

return cipher;

} catch (Exception e) {

throw new RuntimeException("AESUtil:initParam fail!", e);

}

}

public static void main(String[] args) {

long s = System.currentTimeMillis();

String text = "xxxxx";

String encryptMsg = encrypt(secretKey, text);

System.out.println("密文为:" + encryptMsg);

long e = System.currentTimeMillis();

System.out.println(e-s);

String decryptMsg = decrypt(secretKey, encryptMsg);

System.out.println("明文为:" + decryptMsg);

long d = System.currentTimeMillis();

System.out.println(d-e);

}

}

如果使用 32 位秘钥的时候如下报错:

java.security.InvalidKeyException: Illegal key size

at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1024)

at javax.crypto.Cipher.implInit(Cipher.java:790)

at javax.crypto.Cipher.chooseProvider(Cipher.java:849)

at javax.crypto.Cipher.init(Cipher.java:1348)

...........

我们需要找到java版本对应的两个jar包放到jdk目录中的/jre/lib/security目录下,如果

95bccc7abd5a44f263591ed171012174.png

注意: 在高并发的情况下,加密,解密的性能问题,选择合适的加密方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值