From d62dc0310a5169b8bd3d87adc85e721c10094295 Mon Sep 17 00:00:00 2001 From: thinkgem Date: Tue, 23 Jul 2024 19:39:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20encrypt.defaultKey=20?= =?UTF-8?q?=E5=8F=82=E6=95=B0=EF=BC=8C=E9=80=82=E7=94=A8=E4=BA=8E=20Aes?= =?UTF-8?q?=E3=80=81M3=20=E5=8A=A0=E5=AF=86=E7=9A=84=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E7=A7=98=E9=92=A5;=E6=96=B0=E5=A2=9E=20encrypt.storeBase64=20?= =?UTF-8?q?=E5=8F=82=E6=95=B0=EF=BC=8C=E6=98=AF=E5=90=A6=E5=B0=86=20Hex=20?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E6=94=B9=E4=B8=BA=20Base64=20=E7=BC=96?= =?UTF-8?q?=E7=A0=81=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jeesite/common/codec/AesUtils.java | 205 ++++++++---------- .../com/jeesite/common/codec/Sha1Utils.java | 52 ++++- 2 files changed, 135 insertions(+), 122 deletions(-) diff --git a/common/src/main/java/com/jeesite/common/codec/AesUtils.java b/common/src/main/java/com/jeesite/common/codec/AesUtils.java index 036c1e35..e7f4aead 100644 --- a/common/src/main/java/com/jeesite/common/codec/AesUtils.java +++ b/common/src/main/java/com/jeesite/common/codec/AesUtils.java @@ -4,176 +4,175 @@ */ package com.jeesite.common.codec; -import java.io.UnsupportedEncodingException; -import java.security.GeneralSecurityException; -import java.security.SecureRandom; +import com.jeesite.common.io.PropertiesUtils; +import com.jeesite.common.lang.ExceptionUtils; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; - -import com.jeesite.common.lang.ExceptionUtils; +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.security.SecureRandom; /** - * AES加密解密工具类 + * AES 加密解密工具类 * @author ThinkGem */ public class AesUtils { private static final String AES = "AES"; private static final String AES_CBC = "AES/CBC/PKCS5Padding"; - private static final int DEFAULT_AES_KEYSIZE = 128; // 生成AES密钥, 默认长度为128位(16字节). - private static final int DEFAULT_IVSIZE = 16; // 生成随机向量, 默认大小为cipher.getBlockSize(), 16字节 + private static final int DEFAULT_KEY_SIZE = 128; // 生成AES密钥, 默认长度为128位(16字节). + private static final int DEFAULT_IV_SIZE = 16; // 生成随机向量, 默认大小为cipher.getBlockSize(), 16字节 private static final SecureRandom RANDOM = new SecureRandom(); // 用于 生成 generateIV随机数对象 - private static final byte[] DEFAULT_KEY = new byte[]{-97,88,-94,9,70,-76,126,25,0,3,-20,113,108,28,69,125}; + private static final byte[] DEFAULT_KEY = EncodeUtils.decodeHex(PropertiesUtils.getInstance() + .getProperty("encrypt.defaultKey", "9f58a20946b47e190003ec716c1c457d")); + private static final boolean STORE_BASE64 = PropertiesUtils.getInstance() + .getPropertyToBoolean("encrypt.storeBase64", "false"); /** - * 生成AES密钥,返回字节数组, 默认长度为128位(16字节). - */ - public static String genKeyString() { - return EncodeUtils.encodeHex(genKey(DEFAULT_AES_KEYSIZE)); - } - - /** - * 使用AES加密原始字符串. - * - * @param input 原始输入字符数组 - */ - public static String encode(String input) { - try { - return EncodeUtils.encodeHex(encode(input.getBytes(EncodeUtils.UTF_8), DEFAULT_KEY)); - } catch (UnsupportedEncodingException e) { - return ""; - } - } - - /** - * 使用AES加密原始字符串. - * - * @param input 原始输入字符数组 - * @param key 符合AES要求的密钥 - */ - public static String encode(String input, String key) { - try { - return EncodeUtils.encodeHex(encode(input.getBytes(EncodeUtils.UTF_8), EncodeUtils.decodeHex(key))); - } catch (UnsupportedEncodingException e) { - return ""; - } - } - - /** - * 使用AES解密字符串, 返回原始字符串. - * - * @param input Hex编码的加密字符串 - */ - public static String decode(String input) { - try { - return new String(decode(EncodeUtils.decodeHex(input), DEFAULT_KEY), EncodeUtils.UTF_8); - } catch (UnsupportedEncodingException e) { - return ""; - } - } - - /** - * 使用AES解密字符串, 返回原始字符串. - * - * @param input Hex编码的加密字符串 - * @param key 符合AES要求的密钥 - */ - public static String decode(String input, String key) { - try { - return new String(decode(EncodeUtils.decodeHex(input), EncodeUtils.decodeHex(key)), EncodeUtils.UTF_8); - } catch (UnsupportedEncodingException e) { - return ""; - } - } - - /** - * 生成AES密钥,返回字节数组, 默认长度为128位(16字节). + * 生成 AES 密钥,返回字节数组, 默认长度为128位(16字节) */ public static byte[] genKey() { - return genKey(DEFAULT_AES_KEYSIZE); + return genKey(DEFAULT_KEY_SIZE); } /** - * 生成AES密钥,可选长度为128,192,256位. + * 生成 AES 密钥, 返回字节数组, 默认长度为128位(16字节) */ - public static byte[] genKey(int keysize) { + public static String genKeyString() { + return EncodeUtils.encodeHex(genKey()); + } + + /** + * 生成 AES 密钥, 可选长度为128,192,256位 + */ + public static byte[] genKey(int keySize) { try { KeyGenerator keyGenerator = KeyGenerator.getInstance(AES); - keyGenerator.init(keysize); + keyGenerator.init(keySize); SecretKey secretKey = keyGenerator.generateKey(); return secretKey.getEncoded(); } catch (GeneralSecurityException e) { throw ExceptionUtils.unchecked(e); } } - + /** - * 生成随机向量,默认大小为cipher.getBlockSize(), 16字节. + * 生成随机向量, 默认大小为cipher.getBlockSize(), 16字节 */ public static byte[] genIV() { - byte[] bytes = new byte[DEFAULT_IVSIZE]; + byte[] bytes = new byte[DEFAULT_IV_SIZE]; RANDOM.nextBytes(bytes); return bytes; } + + /** + * 使用 AES 加密原始字符串 + * @param input 原始输入字符串 + * @author ThinkGem + */ + public static String encode(String input) { + if (STORE_BASE64) { + return EncodeUtils.encodeBase64(encode(input.getBytes(StandardCharsets.UTF_8), DEFAULT_KEY)); + } + return EncodeUtils.encodeHex(encode(input.getBytes(StandardCharsets.UTF_8), DEFAULT_KEY)); + } /** - * 使用AES加密原始字符串. - * + * 使用 AES 加密原始字符串 * @param input 原始输入字符数组 - * @param key 符合AES要求的密钥 + * @param key 符合要求的密钥 + * @author ThinkGem */ public static byte[] encode(byte[] input, byte[] key) { return aes(input, key, Cipher.ENCRYPT_MODE); } /** - * 使用AES加密原始字符串. - * + * 使用 AES 加密原始字符串 + * @param input 原始输入字符串 + * @param key 符合要求的密钥 + * @author ThinkGem + */ + public static String encode(String input, String key) { + if (STORE_BASE64) { + return EncodeUtils.encodeBase64(encode(input.getBytes(StandardCharsets.UTF_8), EncodeUtils.decodeHex(key))); + } + return EncodeUtils.encodeHex(encode(input.getBytes(StandardCharsets.UTF_8), EncodeUtils.decodeHex(key))); + } + + /** + * 使用 AES 加密原始字符串 * @param input 原始输入字符数组 - * @param key 符合AES要求的密钥 + * @param key 符合要求的密钥 * @param iv 初始向量 + * @author ThinkGem */ public static byte[] encode(byte[] input, byte[] key, byte[] iv) { return aes(input, key, iv, Cipher.ENCRYPT_MODE); } + + /** + * 使用 AES 解密数据, 返回原始字符串 + * @param input Hex 或 Base64 编码的加密字符串 + * @author ThinkGem + */ + public static String decode(String input) { + if (STORE_BASE64) { + return new String(decode(EncodeUtils.decodeBase64(input), DEFAULT_KEY), StandardCharsets.UTF_8); + } + return new String(decode(EncodeUtils.decodeHex(input), DEFAULT_KEY), StandardCharsets.UTF_8); + } /** - * 使用AES解密字符串, 返回原始字符串. - * - * @param input Hex编码的加密字符串 - * @param key 符合AES要求的密钥 + * 使用 AES 解密数据, 返回原始字符串 + * @param input 加密输入字符数组 + * @param key 符合要求的密钥 + * @author ThinkGem */ public static byte[] decode(byte[] input, byte[] key) { return aes(input, key, Cipher.DECRYPT_MODE); } /** - * 使用AES解密字符串, 返回原始字符串. - * + * 使用 AES 解密数据, 返回原始字符串 + * @param input Hex 或 Base64 编码的加密字符串 + * @param key 符合要求的密钥 + * @author ThinkGem + */ + public static String decode(String input, String key) { + if (STORE_BASE64) { + return new String(decode(EncodeUtils.decodeBase64(input), EncodeUtils.decodeHex(key)), StandardCharsets.UTF_8); + } + return new String(decode(EncodeUtils.decodeHex(input), EncodeUtils.decodeHex(key)), StandardCharsets.UTF_8); + } + + /** + * 使用 AES 解密数据, 返回原始字符串 * @param input Hex编码的加密字符串 * @param key 符合AES要求的密钥 * @param iv 初始向量 + * @author ThinkGem */ public static byte[] decode(byte[] input, byte[] key, byte[] iv) { return aes(input, key, iv, Cipher.DECRYPT_MODE); } /** - * 使用AES加密或解密无编码的原始字节数组, 返回无编码的字节数组结果. - * + * 使用 AES 加密或解密无编码的原始字节数组, 返回无编码的字节数组结果 * @param input 原始字节数组 * @param key 符合AES要求的密钥 * @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE + * @author ThinkGem */ private static byte[] aes(byte[] input, byte[] key, int mode) { try { - SecretKey secretKey = new SecretKeySpec(key, AES); Cipher cipher = Cipher.getInstance(AES); + SecretKey secretKey = new SecretKeySpec(key, AES); cipher.init(mode, secretKey); return cipher.doFinal(input); } catch (GeneralSecurityException e) { @@ -182,18 +181,18 @@ public class AesUtils { } /** - * 使用AES加密或解密无编码的原始字节数组, 返回无编码的字节数组结果. - * + * 使用 AES 加密或解密无编码的原始字节数组, 返回无编码的字节数组结果 * @param input 原始字节数组 * @param key 符合AES要求的密钥 * @param iv 初始向量 * @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE + * @author ThinkGem */ private static byte[] aes(byte[] input, byte[] key, byte[] iv, int mode) { try { + Cipher cipher = Cipher.getInstance(AES_CBC); SecretKey secretKey = new SecretKeySpec(key, AES); IvParameterSpec ivSpec = new IvParameterSpec(iv); - Cipher cipher = Cipher.getInstance(AES_CBC); cipher.init(mode, secretKey, ivSpec); return cipher.doFinal(input); } catch (GeneralSecurityException e) { @@ -201,18 +200,4 @@ public class AesUtils { } } -// public static void main(String[] args) { -// -// String s = "hello word!"; -// System.out.println(s); -// -// String k = genKeyString(); -// System.out.println(k); -// String ss = encode(s, k); -// System.out.println(ss); -// String sss = decode(ss, k); -// System.out.println(sss); -// -// } - } \ No newline at end of file diff --git a/common/src/main/java/com/jeesite/common/codec/Sha1Utils.java b/common/src/main/java/com/jeesite/common/codec/Sha1Utils.java index a45c15a7..dd7718df 100644 --- a/common/src/main/java/com/jeesite/common/codec/Sha1Utils.java +++ b/common/src/main/java/com/jeesite/common/codec/Sha1Utils.java @@ -6,17 +6,16 @@ package com.jeesite.common.codec; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; /** - * SHA-1不可逆加密工具类 + * SHA-1 加密工具类,散列加密,不可逆加密 * @author ThinkGem */ public class Sha1Utils { - private static final String SHA1 = "SHA-1"; - /** - * 生成随机的Byte[]作为salt密钥. + * 生成随机的 Byte[] 作为 salt 密钥. * @param numBytes byte数组的大小 */ public static byte[] genSalt(int numBytes) { @@ -24,31 +23,60 @@ public class Sha1Utils { } /** - * 对输入字符串进行sha1散列. + * 生成随机的 Byte[] 作为 salt 密钥,返回 HEX 值 + * @param numBytes byte 数组的大小 + */ + public static String genSaltString(int numBytes) { + return DigestUtils.genSaltString(numBytes); + } + + /** + * 对输入字符串进行 SHA-1 散列. */ public static byte[] sha1(byte[] input) { - return DigestUtils.digest(input, SHA1, null, 1); + return DigestUtils.digest(input, DigestUtils.SHA1, null, 1); } /** - * 对输入字符串进行sha1散列. + * 对输入字符串进行 SHA-1 散列. + */ + public static String sha1(String input) { + return EncodeUtils.encodeHex(sha1(input.getBytes(StandardCharsets.UTF_8))); + } + + /** + * 对输入字符串进行 SHA-1 散列. */ public static byte[] sha1(byte[] input, byte[] salt) { - return DigestUtils.digest(input, SHA1, salt, 1); + return DigestUtils.digest(input, DigestUtils.SHA1, salt, 1); } /** - * 对输入字符串进行sha1散列. + * 对输入字符串进行 SHA-1 散列. + */ + public static String sha1(String data, String salt) { + return EncodeUtils.encodeHex(sha1(data.getBytes(StandardCharsets.UTF_8), EncodeUtils.decodeHex(salt))); + } + + /** + * 对输入字符串进行 SHA-1 散列. */ public static byte[] sha1(byte[] input, byte[] salt, int iterations) { - return DigestUtils.digest(input, SHA1, salt, iterations); + return DigestUtils.digest(input, DigestUtils.SHA1, salt, iterations); } /** - * 对文件进行sha1散列. + * 对输入字符串进行 SHA-1 散列. + */ + public static String sha1(String input, String salt, int iterations) { + return EncodeUtils.encodeHex(sha1(input.getBytes(StandardCharsets.UTF_8), EncodeUtils.decodeHex(salt), iterations)); + } + + /** + * 对文件进行 SHA-1 散列. */ public static byte[] sha1(InputStream input) throws IOException { - return DigestUtils.digest(input, SHA1); + return DigestUtils.digest(input, DigestUtils.SHA1); } }