作为开发者,我们都知道组件化、标准化和代码复用的重要性。数据加密也从未停止过对算法组件化的尝试,产生了各式各样的算法组合。从手工加密阶段,到计算机加密阶段。密码学应用不再局限于军事、政治和外交领域,逐步扩大到商务、金融和社会的其他领域。密码学的研究和应用已大规模扩展到了民用方面。
现有需求:传输压缩文件 从A端 - B端 压缩文件中包含数据块文件,json文件。
需最大程度防止文件泄露 以及被篡改。
根据上述需求。我们采用消息摘要算法 对称加密算法 以及 非对称加密算法来实现。
思路
1 对块文件进行SHA256加密
2 对得到的密文 使用私钥进行加密
3 将加密后的密文存入 json文件中
4 将json文件用私钥加密成密文文件
5 将数据从A端 运输至 B端
6 使用公钥解密密文文件
7 将明文json文件中密文sha256取出
8 公钥解密密文
9 将明文sha256 和 B端校验 确认无篡改
工具类
import java.io.File;
import java.io.IOException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.MessageDigestAlgorithms;
import java.util.Base64;
/**
* SHA计算工具
* @author ivhen
*
*/
public class ShaUtil {
/**
* 计算文件 SHA值 1 256 512 sha3
* @param filePath
* @param messageDigestAlgorithms
* @return
*/
public static String getSHA(String filePath, String messageDigestAlgorithms) {
String hex = null;
try {
File file = new File(filePath);
hex = new DigestUtils(messageDigestAlgorithms).digestAsHex(file);
} catch (IOException e) {
e.printStackTrace();
}
return hex;
}
}
对称加密和非对称加密
import java.io.*;
/**
* 实现对文件加解密
*
* @author ivhen
*/
public class IOSercet {
//获取系统类型
private static String OS = System.getProperty("os.name").toLowerCase();
//加密后的路径
public static final String secretFilePath = "F:/secret/";
//解密后的路径
public static final String decrypFilePath = "F:/decrypt/";
/**
* 批量解密
* 适用于加密文件的路径和解密后的路径不一样的业务场景
* 获取指定目录下的所有文件及子类文件夹下的所有文件
*
* @param path 指定需要解密的目录
*/
public static void getAllFileNameSecret(String path) {
File file = new File(path);
File[] tempList = file.listFiles();
for (int i = 0; i < tempList.length; i++) {
if (tempList[i].isFile()) {
System.out.println("文 件:" + tempList[i]);
secret(tempList[i].toString());
}
if (tempList[i].isDirectory()) {
System.out.println("文件夹:" + tempList[i]);
getAllFileNameSecret(tempList[i].getAbsolutePath());
}
}
return;
}
/**
* 批量解密
* 适用于加密文件的路径和解密后的路径不一样的业务场景
* 获取指定目录下的所有文件及子类文件夹下的所有文件
*
* @param path 指定需要解密的目录
*/
public static void getAllFileNameDecrypt(String path) {
File file = new File(path);
File[] tempList = file.listFiles();
for (int i = 0; i < tempList.length; i++) {
if (tempList[i].isFile()) {
System.out.println("文 件:" + tempList[i]);
decrypt(tempList[i].toString());
}
if (tempList[i].isDirectory()) {
System.out.println("文件夹:" + tempList[i]);
getAllFileNameDecrypt(tempList[i].getAbsolutePath());
}
}
return;
}
/**
* 批量加密
* 适用于源路径和加密后的路径不一样的业务场景
*
* @param srcFileName 源文件名称
*/
public static void secret(String srcFileName) {
long a = 0;
long b = 0;
createDir(secretFilePath);
String secretFileName = getFileName(srcFileName);
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFileName));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(secretFilePath + secretFileName));
int n;
a = System.currentTimeMillis();
while ((n = bis.read()) != -1) {
bos.write(n + 1);
}
b = System.currentTimeMillis();
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("加密拷贝成功!");
System.out.println("加密用时:" + (b - a) + "ms");
}
/**
* 批量解密
* 适用于加密文件的路径和解密后的路径不一样的业务场景
*
* @param secretFileName 加密的文件名称
*/
public static void decrypt(String secretFileName) {
long a = 0;
long b = 0;
try {
createDir(decrypFilePath);
String decryptFileName = getFileName(secretFileName);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(secretFileName));
BufferedOutputStream bos = new BufferedOutputStream(new
FileOutputStream(decrypFilePath + decryptFileName));
int n;
a = System.currentTimeMillis();
while ((n = bis.read()) != -1) {
bos.write(n - 1);
}
b = System.currentTimeMillis();
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("解密拷贝成功!");
System.out.println("解密用时:" + (b - a) + "ms");
}
/**
* 目录不存在,则批量创建
*
* @param fileDir
*/
public static void createDir(String fileDir) {
File file = new File(fileDir);
//如果文件夹不存在则创建
if (!file.exists() && !file.isDirectory()) {
System.out.println("//不存在");
file.mkdirs();
}
}
/**
* 文件名称处理
*
* @param dealFileName
* @return
*/
public static String getFileName(String dealFileName) {
if (OS.indexOf("windows") >= 0) {
//windows
return dealFileName.substring(dealFileName.lastIndexOf("\\") + 1);
} else {
//linux
return dealFileName.substring(dealFileName.lastIndexOf("/") + 1);
}
}
}
continue…