Bootstrap

Java日志AES256+base64加密生成txt文件打包zip上传ftp一条龙

引入pom依赖

	<dependency>
		<groupId>commons-net</groupId>
		<artifactId>commons-net</artifactId>
		<version>3.1</version>
	</dependency>

yml配置文件

logServer:
  #文件AES加密需要的密钥
  logSecretKey: uBdUx82vPHkDKb284d7NkjFoNcKWBuka
  #文件暂存本地服务器目录
  localLogPath: d:\\ftp\\gd
  #目标服务器的ftp相关配置
  ip: ***.***.***.***
  port: **
  username: ******
  password: ******
  basePath: /home/myftp
  filePath: /TQGD

AES256工具类

public class AES256Util {
    /**
     * 密钥, 256位32个字节
     */
    public static final String DEFAULT_SECRET_KEY = "uBdUx82vPHkDKb284d7NkjFoNcKWBuka";

    private static final String AES = "AES";

    /**
     * 初始向量IV, 初始向量IV的长度规定为128位16个字节, 初始向量的来源为随机生成.
     */
    private static final byte[] KEY_VI = "c558Gq0YQK2QUlMc".getBytes();

    /**
     * 加密解密算法/加密模式/填充方式
     */
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

    private static java.util.Base64.Encoder base64Encoder = java.util.Base64.getEncoder();
    private static java.util.Base64.Decoder base64Decoder = java.util.Base64.getDecoder();

    static {
        java.security.Security.setProperty("crypto.policy", "unlimited");
    }

    /**
     * AES加密
     */
    public static String encode(String key, String content) {
        try {
            javax.crypto.SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(key.getBytes(), AES);
            javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(KEY_VI));

            // 获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
            byte[] byteEncode = content.getBytes(java.nio.charset.StandardCharsets.UTF_8);

            // 根据密码器的初始化方式加密
            byte[] byteAES = cipher.doFinal(byteEncode);

            // 将加密后的数据转换为字符串
            return base64Encoder.encodeToString(byteAES);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * AES解密
     */
    public static String decode(String key, String content) {
        try {
            javax.crypto.SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(key.getBytes(), AES);
            javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(javax.crypto.Cipher.DECRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(KEY_VI));

            // 将加密并编码后的内容解码成字节数组
            byte[] byteContent = base64Decoder.decode(content);
            // 解密
            byte[] byteDecode = cipher.doFinal(byteContent);
            return new String(byteDecode, java.nio.charset.StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String dbPassword = "123456";
        String encryptDbPwd = AES256Util.encode(DEFAULT_SECRET_KEY, dbPassword);
        System.out.println("encrypt: " + encryptDbPwd);

        String decrypt = AES256Util.decode(DEFAULT_SECRET_KEY, encryptDbPwd);
        System.out.println("decrypt:" + decrypt);
    }
}

ftp工具类

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * @Author R0137 csy
 * @Date 2022/11/7 14:12
 */
@Slf4j
public class FTPUtil {
    /**
     * Description: 向FTP服务器上传文件
     * @param host FTP服务器hostname
     * @param port FTP服务器端口
     * @param username FTP登录账号
     * @param password FTP登录密码
     * @param basePath FTP服务器基础目录
     * @param filePath FTP服务器文件存放路径。文件的路径为basePath+filePath
     * @param filename 上传到FTP服务器上的文件名
     * @param input 输入流
     * @return 成功返回true,否则返回false
     */
    public static boolean uploadFile(String host, int port, String username, String password, String basePath,
                                     String filePath, String filename, InputStream input) {
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(host, port);// 连接FTP服务器
            // 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(username, password);// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                log.info("ftp服务器登录失败!");
                return false;
            }
            log.info("ftp服务器登录成功!");
            //切换到上传目录
            if (!ftp.changeWorkingDirectory(basePath+filePath)) {
                //如果目录不存在创建目录
                String[] dirs = filePath.split(File.separator);
                String tempPath = basePath;
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir)) continue;
                    tempPath += File.separator + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)) {  //进不去目录,说明该目录不存在
                        if (!ftp.makeDirectory(tempPath)) { //创建目录
                            //如果创建文件目录失败,则返回
                            log.info("创建文件目录{}失败!",tempPath);
                            return false;
                        } else {
                            //目录存在,则直接进入该目录
                            ftp.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            //设置上传文件的类型为二进制类型
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.setControlEncoding("UTF-8");
            //ftp通信有两种模式
            //PORT(主动模式)客户端开通一个新端口(>1024)并通过这个端口发送命令或传输数据,期间服务端只使用他开通的一个端口,例如21
            //PASV(被动模式)客户端向服务端发送一个PASV命令,服务端开启一个新端口(>1024),并使用这个端口与客户端的21端口传输数据
            //由于客户端不可控,防火墙等原因,所以需要由服务端开启端口,需要设置被动模式
            ftp.enterLocalPassiveMode();
            //上传文件,filename需要处理一下,不然中文的名字上传到ftp服务器是乱码的
            if (!ftp.storeFile(new String(filename.getBytes(), StandardCharsets.ISO_8859_1), input)) {
                return false;
            }
            input.close();
            ftp.logout();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return true;
    }

    /**
     * Description: 从FTP服务器下载文件
     * @param host FTP服务器hostname
     * @param port FTP服务器端口
     * @param username FTP登录账号
     * @param password FTP登录密码
     * @param remotePath FTP服务器上的相对路径
     * @param fileName 要下载的文件名
     * @param localPath 下载后保存到本地的路径
     * @return
     */
    public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
                                       String fileName, String localPath) {
        boolean result = false;
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(host, port);
            // 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(username, password);// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return result;
            }
            ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
            FTPFile[] fs = ftp.listFiles();
            for (FTPFile ff : fs) {
                if (ff.getName().equals(fileName)) {
                    File localFile = new File(localPath + File.separator + ff.getName());

                    OutputStream is = new FileOutputStream(localFile);
                    ftp.retrieveFile(ff.getName(), is);
                    is.close();
                }
            }
            ftp.logout();
            result = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return result;
    }

    //ftp上传文件测试main函数
    public static void main(String[] args) {
        //上传
        try {
            FileInputStream in=new FileInputStream(new File("d:\\ftp\\gd\\GD日志需求11.02.docx"));
            boolean flag = uploadFile("192.168.2.124", 21, "myftp", "myftp", "/home/myftp","/TQGD", "GD日志需求11.02.docx", in);
            System.out.println(flag);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        //下载
        boolean b = downloadFile("ip", 21, "username", "password", "/text/wenjian", "hello.txt", "D://");
        System.out.println(b);
    }
}

主程序

	import com.alibaba.fastjson.JSON;
	import lombok.extern.slf4j.Slf4j;
	import org.jeecg.common.api.dto.LogDTO;
	import org.jeecg.common.api.dto.LogVO;
	import org.jeecg.common.util.DateUtils;
	import org.jeecg.common.util.FTPUtil;
	import org.jeecg.common.util.security.AES256Util;
	import org.jeecg.modules.interlligence.mapper.SysLogMapper;
	import org.jeecg.modules.interlligence.service.GDLogService;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.beans.factory.annotation.Value;
	import org.springframework.stereotype.Service;
	
	import java.io.*;
	import java.time.LocalDateTime;
	import java.time.format.DateTimeFormatter;
	import java.util.List;
	import java.util.zip.ZipEntry;
	import java.util.zip.ZipOutputStream;

    @Value("${logServer.logSecretKey}")
    private String logSecretKey;

    @Value("${logServer.localLogPath}")
    private String localLogPath;

    @Value("${logServer.ip}")
    private String ip;

    @Value("${logServer.port}")
    private int port;

    @Value("${logServer.username}")
    private String username;

    @Value("${logServer.password}")
    private String password;

    @Value("${logServer.basePath}")
    private String basePath;

    @Value("${logServer.filePath}")
    private String filePath;

    @Autowired
    private SysLogMapper sysLogMapper;

public void updateLogFileToServer(){
        String formatStr = "yyyy-MM-dd HH:mm:ss";
        DateTimeFormatter fmTime = DateTimeFormatter.ofPattern(formatStr);
        LocalDateTime txtStart = LocalDateTime.now();
        log.info("开始生成日志txt文件,开始时间:{}",txtStart.format(fmTime));

        List<LogDTO> logList = sysLogMapper.getSysLogByTime(DateUtils.getLastNMinString(2 * 60,formatStr),DateUtils.getLastNMinString(0,formatStr));
        log.info("日志数量为{}。",logList.size());
        StringBuilder result = new StringBuilder();
        for (LogDTO dto : logList) {
            result.append(AES256Util.encode(logSecretKey, JSON.toJSONString(dto))).append("\n");
        }
        //生成txt文件到服务器本地
        File file = new File(localLogPath);
        if(!file.exists()){
            file.mkdir();
        }
        String txtFileName = file + File.separator + System.currentTimeMillis() + ".txt";
        try {
            BufferedWriter out = new BufferedWriter(new FileWriter(txtFileName));
            out.write(result.toString());
            //把缓存区内容压入文件
            out.flush();
            out.close();

            LocalDateTime txtEnd = LocalDateTime.now();
            log.info("txt文件生成成功!开始压缩成zip文件。时间:{}",txtEnd.format(fmTime));

            DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
            LocalDateTime zipFileDate = LocalDateTime.now();
            String zipFileName = localLogPath + File.separator + System.currentTimeMillis() + zipFileDate.format(format) + ".zip";
            File zipFile = new File(zipFileName);
            FileOutputStream zipFileOut = new FileOutputStream(zipFile);
            ZipOutputStream zipFileStream = new ZipOutputStream(zipFileOut);
            byte[] buf = new byte[2048];
            File textFile = new File(txtFileName);
            zipFileStream.putNextEntry(new ZipEntry(textFile.getName()));
            int len;
            FileInputStream in = new FileInputStream(textFile);
            while ((len = in.read(buf)) != -1){
                zipFileStream.write(buf, 0, len);
            }
            zipFileStream.closeEntry();
            in.close();
            zipFileStream.close();

            LocalDateTime zipEnd = LocalDateTime.now();
            log.info("zip文件生成成功!开始上传ftp服务器。时间:{}",zipEnd.format(fmTime));

            boolean uploadResult = FTPUtil.uploadFile(ip, port, username, password, basePath, filePath, zipFile.getName(), new FileInputStream(zipFile));
            if(uploadResult){//如果成功,删除服务器产生的缓存文件
                LocalDateTime zipUpload = LocalDateTime.now();
                log.info("zip文件上传成功!时间:{}",zipUpload.format(fmTime));
                textFile.delete();
                zipFile.delete();
            }else{//如果失败,留在服务器上
                log.info("zip文件上传ftp服务器时发生错误,文件名:{}",zipFileName);
            }
        }catch (Exception e){
            log.info("日志生成上传失败!--->"+e.getMessage());
        }
    }
遇到报错:java.security.InvalidKeyException: Illegal key size
参考https://blog.csdn.net/zhuwangxiangbie/article/details/105124612
	https://blog.csdn.net/Linlietao0587/article/details/124823968
其中需要替换jre两个jar包,如果官网下载不下来,可以访问 https://wwi.lanzoup.com/iXGs404zm1dg(jdk8)
;