From 4c77c4ebe89db3c6bbdd2db804edb413ffcc713a Mon Sep 17 00:00:00 2001 From: yexuejc <1107047387@qq.com> Date: Fri, 11 Nov 2022 19:25:46 +0800 Subject: [PATCH] =?UTF-8?q?AES=E5=8A=A0=E8=A7=A3=E5=AF=86=20=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=8E=8B=E7=BC=A9=20FileUtil.base64ToStr=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20=E5=85=BC=E5=AE=B9jdk11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 25 ++- .../java/com/yexuejc/base/encrypt/AES.java | 173 ++++++++++++++++++ .../yexuejc/base/pojo/CreateZipFileBean.java | 90 +++++++++ .../java/com/yexuejc/base/pojo/PagerVO.java | 1 - .../java/com/yexuejc/base/util/FileUtil.java | 51 +++--- .../java/com/yexuejc/base/util/ZipUtil.java | 65 +++++++ 6 files changed, 367 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/yexuejc/base/encrypt/AES.java create mode 100644 src/main/java/com/yexuejc/base/pojo/CreateZipFileBean.java create mode 100644 src/main/java/com/yexuejc/base/util/ZipUtil.java diff --git a/pom.xml b/pom.xml index b84065c..159f31d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,16 +6,16 @@ top.yexuejc yexuejc-base - 1.5.0-jre8 + 1.5.1-jdk11 yexuejc-base https://github.com/yexuejc/yexuejc-base - Common toolkits based on JDK8 packaging + Common toolkits based on JDK11 packaging The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt + https://www.apache.org/licenses/LICENSE-2.0.txt @@ -44,14 +44,15 @@ https://jitpack.io 0.11.5 true - 1.8 - 3.0.1 + 11 + 3.0.2 2.11.0 1.70 31.1-jre 5.2.2 - 2.13.2 + 2.14.0 + 2.11.2 UTF-8 UTF-8 @@ -118,10 +119,16 @@ ${jackson.version} + + net.lingala.zip4j + zip4j + ${zip4j.version} + + org.junit.jupiter junit-jupiter-api - 5.8.1 + 5.9.0 test @@ -136,8 +143,8 @@ 3.8.1 UTF-8 - 8 - 8 + 11 + 11 diff --git a/src/main/java/com/yexuejc/base/encrypt/AES.java b/src/main/java/com/yexuejc/base/encrypt/AES.java new file mode 100644 index 0000000..0941afa --- /dev/null +++ b/src/main/java/com/yexuejc/base/encrypt/AES.java @@ -0,0 +1,173 @@ +package com.yexuejc.base.encrypt; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +/** + * AES加解密 + * + * @author maxf + * @class-name AES + * @description + * @date 2022/11/11 15:36 + */ +public class AES { + public static AES builder() { + return Instace.aes; + } + + private static class Instace { + private static AES aes = new AES(); + } + + public static final String AES_ALGORITHM = "AES"; + + /** + * 加密模式 + */ + public static enum ALGORITHM { + //算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度 + //AES/CBC/NoPadding 16 不支持 + AES_CBC_NoPadding("AES/CBC/NoPadding"), + //AES/CBC/PKCS5Padding 32 16 + AES_CBC_PKCS5Padding("AES/CBC/PKCS5Padding"), + //AES/CBC/ISO10126Padding 32 16 + AES_CBC_ISO10126Padding("AES/CBC/ISO10126Padding"), + //AES/CFB/NoPadding 16 原始数据长度 + AES_CFB_NoPadding("AES/CFB/NoPadding"), + //AES/CFB/PKCS5Padding 32 16 + AES_CFB_PKCS5Padding("AES/CFB/PKCS5Padding"), + //AES/CFB/ISO10126Padding 32 16 + AES_CFB_ISO10126Padding("AES/CFB/ISO10126Padding"), + //AES/ECB/NoPadding 16 不支持 + AES_ECB_NoPadding("AES/ECB/NoPadding"), + //AES/ECB/PKCS5Padding 32 16 + AES_ECB_PKCS5Padding("AES/ECB/PKCS5Padding"), + //AES/ECB/ISO10126Padding 32 16 + AES_ECB_ISO10126Padding("AES/ECB/ISO10126Padding"), + //AES/OFB/NoPadding 16 原始数据长度 + AES_OFB_NoPadding("AES/OFB/NoPadding"), + //AES/OFB/PKCS5Padding 32 16 + AES_OFB_PKCS5Padding("AES/OFB/PKCS5Padding"), + //AES/OFB/ISO10126Padding 32 16 + AES_OFB_ISO10126Padding("AES/OFB/ISO10126Padding"), + //AES/PCBC/NoPadding 16 不支持 + AES_PCBC_NoPadding("AES/PCBC/NoPadding"), + //AES/PCBC/PKCS5Padding 32 16 + AES_PCBC_PKCS5Padding("AES/PCBC/PKCS5Padding"), + //AES/PCBC/ISO10126Padding 32 16 + AES_PCBC_ISO10126Padding("AES/PCBC/ISO10126Padding"); + public String name; + + ALGORITHM(String name) { + this.name = name; + } + } + + private ALGORITHM algorithm = ALGORITHM.AES_CBC_NoPadding; + private String key = "hj7x89H$yuBI0456"; + private String iv = "NIfb&95GUY86Gfgh"; + private Charset charset = StandardCharsets.UTF_8; + + /** + * 加密 + * + * @param data 明文 + * @return 密文 + * @Description AES算法加密明文 + */ + public String encrypt(String data) throws Exception { + try { + + Cipher cipher = Cipher.getInstance(algorithm.name); + int blockSize = cipher.getBlockSize(); + byte[] dataBytes = data.getBytes(charset); + int plaintextLength = dataBytes.length; + if (plaintextLength % blockSize != 0) { + plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize)); + } + byte[] plaintext = new byte[plaintextLength]; + System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length); + SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM); + IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes(charset)); + cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); + byte[] encrypted = cipher.doFinal(plaintext); + return Base64.getEncoder().encodeToString(encrypted); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 解密 + * + * @param data 密文 + * @return 明文 + * @Description AES算法解密密文 + */ + public String decrypt(String data) throws Exception { + try { + byte[] encrypted = Base64.getDecoder().decode(data); + Cipher cipher = Cipher.getInstance(algorithm.name); + SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM); + IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes(charset)); + cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); + byte[] original = cipher.doFinal(encrypted); + return new String(original, charset).trim(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +// +// public static void main(String[] args) throws Exception { +// String str = " 奥萨蒂 asd8阿斯顿8asd "; +// AES.builder().setAlgorithm(ALGORITHM.AES_CBC_ISO10126Padding); +// AES.builder().setKey("DEsx89H$yuBI0456"); +// String encrypt = AES.builder().encrypt(str); +// System.out.println(encrypt); +// String decrypt = AES.builder().decrypt(encrypt); +// System.out.println(">>>" + decrypt + "<<<"); +// } + + public ALGORITHM getAlgorithm() { + return algorithm; + } + + public AES setAlgorithm(ALGORITHM algorithm) { + this.algorithm = algorithm; + return this; + } + + public String getKey() { + return key; + } + + public AES setKey(String key) { + this.key = key; + return this; + } + + public String getIv() { + return iv; + } + + public AES setIv(String iv) { + this.iv = iv; + return this; + } + + public Charset getCharset() { + return charset; + } + + public AES setCharset(Charset charset) { + this.charset = charset; + return this; + } +} diff --git a/src/main/java/com/yexuejc/base/pojo/CreateZipFileBean.java b/src/main/java/com/yexuejc/base/pojo/CreateZipFileBean.java new file mode 100644 index 0000000..2853609 --- /dev/null +++ b/src/main/java/com/yexuejc/base/pojo/CreateZipFileBean.java @@ -0,0 +1,90 @@ +package com.yexuejc.base.pojo; + +import java.util.List; + +/** + * 压缩文件的参数设定 + * + * @author maxf + * @class-name CreateZipFileBean + * @description 压缩文件参考 {@link com.yexuejc.base.util.ZipUtil} + * @date 2022/11/11 10:30 + */ +public class CreateZipFileBean { + /** + * 压缩的源文件列表,为空表示压缩整个目录 + */ + private List sourceFileName; + /** + * 当压缩文件夹时,需要排除的文件。压缩文件时(该参数无效) + */ + private List excludeFileName; + /** + * 压缩源文件的目录 + */ + private String sourcePath; + /** + * 生成压缩文件路径(全路径+压缩文件名) + */ + private String zipFile; + /** + * 加密密码 + */ + private String encryptPwd; + + private String writeCharsetName = "UTF-8"; + + public List getSourceFileName() { + return sourceFileName; + } + + public String getEncryptPwd() { + return encryptPwd; + } + + public CreateZipFileBean setEncryptPwd(String encryptPwd) { + this.encryptPwd = encryptPwd; + return this; + } + + public CreateZipFileBean setSourceFileName(List sourceFileName) { + this.sourceFileName = sourceFileName; + return this; + } + + public String getSourcePath() { + return sourcePath; + } + + public CreateZipFileBean setSourcePath(String sourcePath) { + this.sourcePath = sourcePath; + return this; + } + + public String getZipFile() { + return zipFile; + } + + public CreateZipFileBean setZipFile(String zipFile) { + this.zipFile = zipFile; + return this; + } + + public String getWriteCharsetName() { + return writeCharsetName; + } + + public CreateZipFileBean setWriteCharsetName(String writeCharsetName) { + this.writeCharsetName = writeCharsetName; + return this; + } + + public List getExcludeFileName() { + return excludeFileName; + } + + public CreateZipFileBean setExcludeFileName(List excludeFileName) { + this.excludeFileName = excludeFileName; + return this; + } +} diff --git a/src/main/java/com/yexuejc/base/pojo/PagerVO.java b/src/main/java/com/yexuejc/base/pojo/PagerVO.java index e23aeda..bf441e4 100644 --- a/src/main/java/com/yexuejc/base/pojo/PagerVO.java +++ b/src/main/java/com/yexuejc/base/pojo/PagerVO.java @@ -4,7 +4,6 @@ import com.yexuejc.base.util.JsonUtil; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; - /** * 分页 VO * diff --git a/src/main/java/com/yexuejc/base/util/FileUtil.java b/src/main/java/com/yexuejc/base/util/FileUtil.java index 956f528..f0d351e 100644 --- a/src/main/java/com/yexuejc/base/util/FileUtil.java +++ b/src/main/java/com/yexuejc/base/util/FileUtil.java @@ -10,12 +10,27 @@ import com.yexuejc.base.pojo.ReadFileBean; import io.jsonwebtoken.lang.Assert; import org.apache.commons.io.IOUtils; -import java.io.*; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.io.Reader; +import java.io.StringWriter; import java.math.BigInteger; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; @@ -159,7 +174,6 @@ public class FileUtil { return null; } - /*** * 计算SHA1码 * @@ -303,41 +317,24 @@ public class FileUtil { * @return */ public static String base64ToStr(File file) { - return new String(base64(file)); - } - - /** - * 获取文件base64 - * - * @param file - * @return - */ - public static byte[] base64(File file) { - FileInputStream fileInputStream = null; - byte[] data = null; - // 读取图片字节数组 try { - fileInputStream = new FileInputStream(file); - data = new byte[fileInputStream.available()]; - fileInputStream.read(data); - fileInputStream.close(); + byte[] bytes = Files.readAllBytes(Path.of(file.getPath())); + return Base64.getEncoder().encodeToString(bytes); } catch (IOException e) { logger.severe("The operation file is an IO exception."); - e.printStackTrace(); } - // 对字节数组Base64编码 - return Base64.getEncoder().encode(data); + return null; } /** * base64转文件 *

* - * 文件转base64请使用 {@link FileUtil#base64(File)} + * 文件转base64请使用 {@link FileUtil#base64ToStr(File)} * * * @param decode {@link FileUtil#base64ToStr(File)} 的结果 - * @param fileName 文件名称(包含路径) + * @param fileName 保存文件名称(包含路径) * @return 返回保存地址 */ public static String base64ToFile(String decode, String fileName) { @@ -348,7 +345,7 @@ public class FileUtil { * base64转文件 *

* - * 文件转base64请使用 {@link FileUtil#base64(File)} + * 文件转base64请使用 {@link FileUtil#base64ToStr(File)} * * * @param decode baseByte @@ -553,7 +550,6 @@ public class FileUtil { return new String(result, charset); } - /** * 提供读取IO流方法合集 *

读取速度快慢顺序:

@@ -614,7 +610,6 @@ public class FileUtil { .collect(Collectors.joining(lineSeparator == null ? System.lineSeparator() : lineSeparator)); } - /** * 读取IO流内容:Scanner A方式 * @@ -637,7 +632,6 @@ public class FileUtil { return new Scanner(inputStream).useDelimiter("\\Z").next(); } - /** * 读取IO流内容:StringBuilder方式 * @@ -741,6 +735,7 @@ public class FileUtil { } } + /*public static void main(String[] args) { long size = FileUtil.size(new File("E:\\OS\\deepin-15.6-amd64\\DeepinCloudPrintServerInstaller_1.0.0.1.exe")); System.out.println(size); diff --git a/src/main/java/com/yexuejc/base/util/ZipUtil.java b/src/main/java/com/yexuejc/base/util/ZipUtil.java new file mode 100644 index 0000000..34df27a --- /dev/null +++ b/src/main/java/com/yexuejc/base/util/ZipUtil.java @@ -0,0 +1,65 @@ +package com.yexuejc.base.util; + +import com.yexuejc.base.pojo.CreateZipFileBean; +import net.lingala.zip4j.ZipFile; +import net.lingala.zip4j.exception.ZipException; +import net.lingala.zip4j.model.ExcludeFileFilter; +import net.lingala.zip4j.model.ZipParameters; +import net.lingala.zip4j.model.enums.CompressionMethod; +import net.lingala.zip4j.model.enums.EncryptionMethod; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 压缩相关 + *

依赖于zip4j:https://github.com/srikanth-lingala/zip4j

+ * + * @author maxf + * @class-name ZipUtil + * @description 文件压缩 + * @date 2022/11/11 11:09 + */ +public class ZipUtil { + + /** + * 创建压缩文件 + * + * @param zipFileBean + */ + public static void createZipFile(CreateZipFileBean zipFileBean) throws ZipException { + ZipParameters zipParameters = new ZipParameters(); + zipParameters.setCompressionMethod(CompressionMethod.STORE); + + //加密 + zipParameters.setEncryptFiles(true); + zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD); + ZipFile zipFile = new ZipFile(zipFileBean.getZipFile()); + if (StrUtil.isNotEmpty(zipFileBean.getEncryptPwd())) { + zipFile = new ZipFile(zipFileBean.getZipFile(), zipFileBean.getEncryptPwd().toCharArray()); + } + if (StrUtil.isNotEmpty(zipFileBean.getSourceFileName())) { + //压缩文件 + List filesToAdd = new ArrayList<>(16); + Map fileNamesMap = new HashMap<>(16); + zipFileBean.getSourceFileName().forEach(it -> { + String file = zipFileBean.getSourcePath() + File.separator + it; + filesToAdd.add(new File(file)); + fileNamesMap.put(file, it); + }); + zipFile.renameFiles(fileNamesMap); + zipFile.addFiles(filesToAdd, zipParameters); + } else { + //压缩目录 + ExcludeFileFilter excludeFileFilter = zipFileBean.getExcludeFileName()::contains; + zipParameters.setExcludeFileFilter(excludeFileFilter); + zipFile.addFolder(new File(zipFileBean.getSourcePath()), zipParameters); + } + } +} + +//checkemun key -> codeMst检索(缓存) +//返回exception(message用区分分割文言和exp) \ No newline at end of file