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

加密方式:

文件名采用简单的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


Java编写文件简单加解密工具_网络Java编写文件简单加解密工具_Java_02


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编写文件简单加解密工具_Java_03