首页 > 编程语言 > 详细

Java编写文件简单加解密工具

时间:2021-08-15 11:34:50      阅读:40      评论:0      收藏:0      [点我收藏+]

本文链接:https://www.cnblogs.com/muphy/p/15142524.html

gitee:https://gitee.com/muphy1112/file-security

因为有些文件在网盘分享或下载会出现违规的情况,特意写了一个工具,不知道效果如何,上传之前需要先加密,下载后在解密

加密方式:

文件名采用简单的base64编码以尝试绕过检索,加密后文件格式为.azi

文件内容加密:读取每个字节根据配置的最简单的密钥加密

 

工具使用方法:

编译

javac FileSecurity.java --encoding UTF-8

加密

java FileSecurity filepath [-e] [secretKey] filepath: 文件或者目录绝对路径 -e:  -e表示加密,-d表示解密,默认值:-e secretKey: 加密密钥,和-e连用,字节类型,取值范围:[-127~-1, 1~127],默认值:1

加密例子,加密后会生成“文件名对应关系.txt”文件

java FileSecurity ./
java FileSecurity D:/tmp/ -e
java FileSecurity D:/tmp/ -e 23

解密

java FileSecurity filepath -d filepath: 文件或者目录绝对路径 -d:  -e表示加密,-d表示解密,默认值:-e

解密例子,解密后也会生成“文件名对应关系.txt”文件

java FileSecurity D:/tmp/ -d

FileSecurity.java

技术分享图片
import java.io.*;
import java.util.Arrays;
import java.util.Base64;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/***
 * 文件加解密
 *
 * @author: 若非
 * @date: 2021/8/15 3:29
 */
public class FileConversion {

    private static ExecutorService executorService;
    private static byte secretKey = 1;
    private static boolean isEncrypt = true;
    private static String currentPath = "./";
    private static AtomicLong count = new AtomicLong(0);
    private static final Base64.Decoder decoder = Base64.getDecoder();
    private static final Base64.Encoder encoder = Base64.getEncoder();
    private static FileWriter fileWriter;

    public static void main(String[] args) throws IOException {
//        System.out.println("VklQ56ysMTT-or77ogYrlpKnnmoTm/gJ3ot6/miJHlupT-or6XmgI7kuYjnkIbmuIXmpZrvvIgz77yJ".replace("-", "/"));
        if (args.length < 1) {
            usage();
            return;
        }
        System.out.println("参数:" + Arrays.toString(args));
        String filepath = args[0];
        System.out.println("操作路径:" + filepath);
        if (args.length > 1) {
            isEncrypt = "-e".equals(args[1]);
            if (isEncrypt) {
                if (args.length > 2) {
                    try {
                        secretKey = Byte.parseByte(args[2]);
                        if (secretKey == 0) {
                            System.out.println("参数错误:加密密钥,字节类型,和-e连用,取值范围:[-127~-1, 1~127],当前值:" + args[2]);
                            usage();
                            return;
                        }
                    } catch (NumberFormatException e) {
                        System.out.println("参数错误:加密密钥,字节类型,和-e连用,取值范围:[-127~-1, 1~127],当前值:" + args[2]);
                        usage();
                        return;
                    }
                }
                System.out.println("密钥:" + secretKey);
            } else {
                if (!"-d".equals(args[1])) {
                    System.out.println("参数错误,无法确认加解密类型,当前值:" + args[1]);
                    usage();
                    return;
                }
            }
        }
        executorService = Executors.newFixedThreadPool(5);
        convert(filepath);
        while (true) {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (count.get() <= 0) {
                executorService.shutdown();
                break;
            }
        }
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        executorService.shutdownNow();
        fileWriter.close();
        System.out.println("完成!");
    }

    private static void usage() {
        System.out.println("usage:");
        System.out.println("java -jar file-conversion.jar filepath [-e | -d] [secretKey]");
        System.out.println("\tfilepath:\t文件或者目录绝对路径");
        System.out.println("\t[-e | -d]:\t-e表示加密,-d表示解密,默认值:-e");
        System.out.println("\tsecretKey:\t加密密钥,和-e连用,字节类型,取值范围:[-127~-1, 1~127],默认值:1");
    }


    public static void convert(String filename) throws IOException {
        if (filename == null || filename.isEmpty()) {
            System.out.println("文件或者目录不存在,文件名:" + filename);
            return;
        }
        File file = new File(filename);
        if (file == null || !file.exists()) {
            System.out.println("文件或者目录不存在,文件名:" + file);
            return;
        }
        if (file.isFile()) {
            currentPath = file.getParentFile().getCanonicalPath();
        } else if (file.isDirectory()) {
            currentPath = file.getCanonicalPath();
        }
        File dir = new File(currentPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        fileWriter = new FileWriter(currentPath + File.separatorChar + "文件名对应关系.txt", true);
        if (isEncrypt) {
            currentPath = currentPath + File.separatorChar + "encrypt";
        } else {
            currentPath = currentPath + File.separatorChar + "decrypt";
        }
        fileWriter.write("输出路径:" + currentPath + "\r\n");
        fileWriter.flush();
        convert(file, "");
    }

    public static void convert(final File file, final String path) throws IOException {
        if (file.isFile()) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    count.incrementAndGet();
                    try {
                        doConvert(file, path);
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        count.decrementAndGet();
                    }
                }
            });
            return;
        }
        if (file.isDirectory() && file.canRead()) {
            for (File f : file.listFiles()) {
                if (f.isDirectory()) {
                    convert(f, path + File.separatorChar + f.getName());
                } else {
                    convert(f, path);
                }
            }
        }
    }

    private static void doConvert(File file, String path) throws IOException {
//        String filename = file.getCanonicalPath();
        if (file.getCanonicalPath().contains(currentPath)) {
            return;
        }
        String outFilepath;
        if (isEncrypt) {
            outFilepath = getEncryptPath(file.getName(), path);
        } else {
            outFilepath = getDecryptPath(file.getName(), path);
        }
        if (outFilepath == null) {
            return;
        }
        File outFile = new File(outFilepath);
        File parentFile = outFile.getParentFile();
        synchronized (fileWriter) {
            if (path.length() > 1) {
                fileWriter.write(path + File.separatorChar + file.getName() + "--->" + path + File.separatorChar + outFile.getName());
            } else {
                fileWriter.write(file.getName() + " ---> " + outFile.getName());
            }
            fileWriter.write("\r\n");
            fileWriter.flush();
        }
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        byte key = secretKey;
        FileOutputStream fos = new FileOutputStream(outFile);
        FileInputStream fis = new FileInputStream(file);
        byte[] buf = new byte[1024];
        int length;
        //循环读取文件内容,输入流中将最多buf.length个字节的数据读入一个buf数组中,返回类型是读取到的字节数。
        //当文件读取到结尾时返回 -1,循环结束。
        if (isEncrypt) {
            fos.write(‘a‘);
            fos.write(‘z‘);
            fos.write(‘i‘);
            fos.write(key);
        } else {
            if (fis.read() != ‘a‘ || fis.read() != ‘z‘ || fis.read() != ‘i‘) {
                System.out.println("解密文件不是azi文件,不能解密,文件名:" + file.getCanonicalPath());
                return;
            }
            key = (byte) fis.read();
        }
        while ((length = fis.read(buf)) != -1) {
            for (int i = 0; i < length; i++) {
                if (isEncrypt) {
                    buf[i] += key;
                } else {
                    buf[i] -= key;
                }
            }
            fos.write(buf, 0, length);
            //System.out.print(new String(buf,0,length));
        }
        //最后记得,关闭流
        fis.close();
        fos.close();
    }

    private static String getDecryptPath(String filename, String path) throws IOException {
        String outFilename = new String(decoder.decode(filename.replaceAll("\\.[aA][zZ][iI]$", "")), "UTF-8").replace("-", "/");
        File outFile = new File(currentPath + path + File.separatorChar + outFilename);
        if (outFile.exists()) {
            System.out.println("解密输出文件已经存在,文件名:" + outFile.getCanonicalPath());
            return null;
        }
        System.out.println("解密文件:" + filename + "--->" + outFilename);
        return outFile.getCanonicalPath();
    }

    private static String getEncryptPath(String filename, String path) throws IOException {
        String outFilename = encoder.encodeToString(filename.getBytes("UTF-8")).replace("/", "-") + ".azi";
        File outFile = new File(currentPath + path + File.separatorChar + outFilename);
        if (outFile.exists()) {
            System.out.println("加密输出文件已经存在,文件名:" + outFile.getCanonicalPath());
            return null;
        }
        System.out.println("加密文件:" + filename + "--->" + outFilename);
        return outFile.getCanonicalPath();
    }
}
查看代码

 技术分享图片

 

Java编写文件简单加解密工具

原文:https://www.cnblogs.com/muphy/p/15142524.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!