当前位置:网站首页>AES/ECB/PKCS5Padding加解密
AES/ECB/PKCS5Padding加解密
2022-08-09 09:07:00 【胡乐天】
注意事项(代码最后附上):
1.测试网站:http://tool.chacuo.net/cryptaes
2.代码中最后的main方法为测试方法,展现了两种输出方式,即base64和hex。
3.java中有效密码为16位/24位/34位,其中如果想使用24位/32位的密码进行加密,需要下载对应jdk的JCE(Java密码扩展无限制权限策略文件),将对应的local_policy.jar和US_export_policy.jar放到%JDK_HOME%\jre\lib\security下,即替换原有两个文件,下方为下载地址。
jdk7:https://www.oracle.com/java/technologies/javase-jce7-downloads.html
jdk8:https://www.oracle.com/java/technologies/javase-jce8-downloads.html
4.类中常量PWD_SIZE=16,是在代码中有限制,如果输入的密文小于16位,会自动补0,此处不需要改变,即使输入24位密钥时,也不需要改变。
代码:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/** *注意: * 1.Java中有效密码为16位/24位/32位,其中24位/32位需要JCE(Java密码扩展无限制权限策略文件),已经下载好(此jar针对jdk8)。 * 2.最后main方法为测试方法 */
public class AesEcbPkcd5Util{
/** * 加密算法 */
private static final String ENCRY_ALGORITHM = "AES";
/** * 加密算法/加密模式/填充类型 * 本例采用AES加密,ECB加密模式,PKCS5Padding填充 */
private static final String CIPHER_MODE = "AES/ECB/PKCS5Padding";
/** * 设置iv偏移量 * 本例采用ECB加密模式,不需要设置iv偏移量 */
private static final String IV_ = null;
/** * 设置加密字符集 * 本例采用 UTF-8 字符集 */
private static final String CHARACTER = "UTF-8";
/** * 设置加密密码处理长度。 * 不足此长度补0; */
private static final int PWD_SIZE = 16;
/** * 密码处理方法 * 如果加解密出问题, * 请先查看本方法,排除密码长度不足填充0字节,导致密码不一致 * @param password 待处理的密码 * @return * @throws UnsupportedEncodingException */
private static byte[] pwdHandler(String password) throws UnsupportedEncodingException {
byte[] data = null;
if (password != null) {
byte[] bytes = password.getBytes(CHARACTER);
if (password.length() < PWD_SIZE) {
System.arraycopy(bytes, 0, data = new byte[PWD_SIZE], 0, bytes.length);
} else {
data = bytes;
}
}
return data;
}
//======================>原始加密<======================
/** * 原始加密 * @param clearTextBytes 明文字节数组,待加密的字节数组 * @param pwdBytes 加密密码字节数组 * @return 返回加密后的密文字节数组,加密错误返回null */
public static byte[] encrypt(byte[] clearTextBytes, byte[] pwdBytes) {
try {
// 1 获取加密密钥
SecretKeySpec keySpec = new SecretKeySpec(pwdBytes, ENCRY_ALGORITHM);
// 2 获取Cipher实例
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
// 查看数据块位数 默认为16(byte) * 8 =128 bit
// System.out.println("数据块位数(byte):" + cipher.getBlockSize());
// 3 初始化Cipher实例。设置执行模式以及加密密钥
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
// 4 执行
byte[] cipherTextBytes = cipher.doFinal(clearTextBytes);
// 5 返回密文字符集
return cipherTextBytes;
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/** * 原始解密 * @param cipherTextBytes 密文字节数组,待解密的字节数组 * @param pwdBytes 解密密码字节数组 * @return 返回解密后的明文字节数组,解密错误返回null */
public static byte[] decrypt(byte[] cipherTextBytes, byte[] pwdBytes) {
try {
// 1 获取解密密钥
SecretKeySpec keySpec = new SecretKeySpec(pwdBytes, ENCRY_ALGORITHM);
// 2 获取Cipher实例
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
// 查看数据块位数 默认为16(byte) * 8 =128 bit
// System.out.println("数据块位数(byte):" + cipher.getBlockSize());
// 3 初始化Cipher实例。设置执行模式以及加密密钥
cipher.init(Cipher.DECRYPT_MODE, keySpec);
// 4 执行
byte[] clearTextBytes = cipher.doFinal(cipherTextBytes);
// 5 返回明文字符集
return clearTextBytes;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// 解密错误 返回null
return null;
}
//======================>BASE64<======================
/** * BASE64加密 * @param clearText 明文,待加密的内容 * @param password 密码,加密的密码 * @return 返回密文,加密后得到的内容。加密错误返回null */
public static String encryptBase64(String clearText, String password) {
try {
// 1 获取加密密文字节数组
byte[] cipherTextBytes = encrypt(clearText.getBytes(CHARACTER), pwdHandler(password));
// 2 对密文字节数组进行BASE64 encoder 得到 BASE6输出的密文
BASE64Encoder base64Encoder = new BASE64Encoder();
String cipherText = base64Encoder.encode(cipherTextBytes);
// 3 返回BASE64输出的密文
return cipherText;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// 加密错误 返回null
return null;
}
/** * BASE64解密 * @param cipherText 密文,带解密的内容 * @param password 密码,解密的密码 * @return 返回明文,解密后得到的内容。解密错误返回null */
public static String decryptBase64(String cipherText, String password) {
try {
// 1 对 BASE64输出的密文进行BASE64 decodebuffer 得到密文字节数组
BASE64Decoder base64Decoder = new BASE64Decoder();
byte[] cipherTextBytes = base64Decoder.decodeBuffer(cipherText);
// 2 对密文字节数组进行解密 得到明文字节数组
byte[] clearTextBytes = decrypt(cipherTextBytes, pwdHandler(password));
// 3 根据 CHARACTER 转码,返回明文字符串
return new String(clearTextBytes, CHARACTER);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// 解密错误返回null
return null;
}
//======================>HEX<======================
/** * HEX加密 * @param clearText 明文,待加密的内容 * @param password 密码,加密的密码 * @return 返回密文,加密后得到的内容。加密错误返回null */
public static String encryptHex(String clearText, String password) {
try {
// 1 获取加密密文字节数组
byte[] cipherTextBytes = encrypt(clearText.getBytes(CHARACTER), pwdHandler(password));
// 2 对密文字节数组进行 转换为 HEX输出密文
String cipherText = byte2hex(cipherTextBytes);
// 3 返回 HEX输出密文
return cipherText;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// 加密错误返回null
return null;
}
/** * HEX解密 * @param cipherText 密文,带解密的内容 * @param password 密码,解密的密码 * @return 返回明文,解密后得到的内容。解密错误返回null */
public static String decryptHex(String cipherText, String password) {
try {
// 1 将HEX输出密文 转为密文字节数组
byte[] cipherTextBytes = hex2byte(cipherText);
// 2 将密文字节数组进行解密 得到明文字节数组
byte[] clearTextBytes = decrypt(cipherTextBytes, pwdHandler(password));
// 3 根据 CHARACTER 转码,返回明文字符串
return new String(clearTextBytes, CHARACTER);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// 解密错误返回null
return null;
}
/*字节数组转成16进制字符串 */
public static String byte2hex(byte[] bytes) {
// 一个字节的数,
StringBuffer sb = new StringBuffer(bytes.length * 2);
String tmp = "";
for (int n = 0; n < bytes.length; n++) {
// 整数转成十六进制表示
tmp = (java.lang.Integer.toHexString(bytes[n] & 0XFF));
if (tmp.length() == 1) {
sb.append("0");
}
sb.append(tmp);
}
return sb.toString().toUpperCase(); // 转成大写
}
/*将hex字符串转换成字节数组 */
private static byte[] hex2byte(String str) {
if (str == null || str.length() < 2) {
return new byte[0];
}
str = str.toLowerCase();
int l = str.length() / 2;
byte[] result = new byte[l];
for (int i = 0; i < l; ++i) {
String tmp = str.substring(2 * i, 2 * i + 2);
result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);
}
return result;
}
/** * 测试加解密 * @param args */
public static void main(String[] args) {
//1.输出设置为base64时
String encryptedStr = encryptBase64("乐天啊", "1234567890123456");//参数:明文,加密字符串
System.out.println("加密后的base64字符串为:"+encryptedStr);
String decrypt = decryptBase64(encryptedStr,"1234567890123456");//参数:密文,加密字符串
System.out.println("解密后的字符串为:" + decrypt);
System.out.println("--------------------------------------------------------------------------------\n\n\n");
//2.输出设置为hex时
String encryptedStr2 = encryptHex("乐天啊", "1234567890123456");//参数:明文,加密字符串
System.out.println("加密后的hex字符串为:"+encryptedStr2);
String decrypt2 = decryptHex(encryptedStr2,"1234567890123456");//参数:密文,加密字符串
System.out.println("解密后的字符串为:" + decrypt2);
}
}
边栏推荐
猜你喜欢
随机推荐
【场景化解决方案】搭建数据桥梁,Dslink打通泛微系统连接流
营养与健康(HIT2021秋)
go Antlr重构脚本解释器如何实现
gin中模型中增删改查+搜索分页
js实现看板全屏功能
C#获取网卡地址
The embedded serial port interrupt can only receive one byte
1. LVGL 8.3 在 Visual Studio 2019 模拟器中的环境搭建
算术表达式求值演示
uniapp编译到小程序后丢失static文件夹问题
PID控制电机输出作为电机PWM占空比输入的理解
The 5th Blue Cap Cup preliminary misc reappears after the game
QT程序生成独立exe程序(避坑版)
小程序调用百度api实现图像识别
微信小程序获取用户收货地址列表wx.chooseAddress
leetcode 34. 在排序数组中查找元素的第一个和最后一个位置(二分经典题)
【场景化解决方案】ERP系统与钉钉实现数据互通
When and How to use MALLOC
UE4 RTS 框选功能实现
Some of the topics in VNCTF2021 are reproduced