作为开发者,我们都知道组件化、标准化和代码复用的重要性。数据加密也从未停止过对算法组件化的尝试,产生了各式各样的算法组合。从手工加密阶段,到计算机加密阶段。密码学应用不再局限于军事、政治和外交领域,逐步扩大到商务、金融和社会的其他领域。密码学的研究和应用已大规模扩展到了民用方面。

现有需求:传输压缩文件 从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…

昨天是历史。明天是谜团。只有今天是天赐的礼物。