Java防止文件被篡改之文件校验和
Java防止文件被篡改之文件校验和
转载:请注明出处,谢谢!
1.为什么要防止文件被篡改?
答案是显然的,为了保证版权,系统安全性等。之前公司开发一个系统,技术核心是一个科学院院士的研究成果,作为一款商业软件来说,保证公司及作者版权是非常重要的。系统安全性就更不用说了,系统两三下就被搞垮了,那这个系统就不算是一个合格的系统。
2.文件校验和作用
我们都知道,一个系统或者软件都是由众多文件组成的。文件校验和的作用就是保证系统版本的正确性和唯一性。具体原理下面会详细解释。
3.文件校验和的原理
思路和实现的方式可能多种多样,我说的是自己的思路和实现方式,请读者自己斟酌使用。
原理:主要有两个核心:
1.每个不同的文件的md5值是不同的
2.每个文件被修改后的md5会发生改变
4.实现思路
1. 拿到系统的根目录
2. 采用递归,遍历目录文件
3. 计算每个文件的md5值 , 并相加。 原因:每个文件md5值不同,相加后的md5值也必定是唯一。 一个md5值占32位,4个字节。大家都知道,1GB = 1024MB ; 1MB = 1024KB; 1KB=1024B ; 1B = 8bit ; 也就是说就算系统有10000个文件,10000*4B/1024 = 39KB 。这个值是远远小于String的最大值的。String 最大值位2GB左右,本人未亲自测试过,数据从网上得来。
4.所有文件的md5值相加后,得到一个总的md5值,并且是唯一的。
5.用户客户端启动时,会先校验文件和,若和服务器中的校验和不一致,则判定客户端非法,禁止其一切行为!
注意:有些文件是一值在改变的,如log日志。故这些一直在变的文件,不应该参与文件校验和计算
5.代码实现
校验文件
public class CheckSystemFolderSum {
// 所有文件md5总和
private static String fileSum = "";
/**
* 遍历文件夹下的所有文件(递归) 并对每个文件计算md5值 得到所有文件的md5值之和
* @param file 软件系统的根文件夹 , suffix 目录文件后缀(以该后缀结尾的目录不会遍历和计算md5值)
* @return 系统所有文件md5之和
*/
public String traverseFolder(File file , String suffix){
if(file == null){
throw new NullPointerException("遍历路径为空路径或非法路径");
}
if (file.exists()) { //判断文件或目录是否存在
File[] files = file.listFiles();
if (files.length == 0) { // 文件夹为空
return null;
} else {
for (File f : files) { // 遍历文件夹
if (f.isDirectory()) { // 判断是否是目录
if(!(f.getName().endsWith(".no"))){ // 如果不是以.no结尾的目录 则计算该目录下的文件的md5值
// 递归遍历
traverseFolder(f,suffix);
}
} else {
// 得到文件的md5值
String string = checkMd5(f);
// 将每个文件的md5值相加
fileSum+=string;
}
}
}
} else {
return null; // 目录不存在
}
return fileSum; // 返回所有文件md5值字符串之和
}
计算文件md5值
/**
* 检验文件生成唯一的md5值 作用:检验文件是否已被修改
* @param file 需要检验的文件
* @return 该文件的md5值
*/
private static String checkMd5(File file) {
// 若输入的参数不是一个文件 则抛出异常
if(!file.isFile()){
throw new NumberFormatException("参数错误!请输入校准文件。");
}
// 定义相关变量
FileInputStream fis = null;
byte[] rb = null;
DigestInputStream digestInputStream = null;
try {
fis = new FileInputStream(file);
MessageDigest md5 = MessageDigest.getInstance("md5");
digestInputStream = new DigestInputStream(fis,md5);
byte[] buffer = new byte[4096];
while (digestInputStream.read(buffer) > 0);
md5 = digestInputStream.getMessageDigest();
rb = md5.digest();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}finally{
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < rb.length; i++) {
String a = Integer.toHexString(0XFF & rb[i]);
if (a.length() < 2) {
a = '0' + a;
}
sb.append(a);
}
return sb.toString(); //得到md5值
}
测试

测试结果没有问题。
源码下载: 请注意,源码文件的包名涉及隐私已被去除,还有代码中的地址等需修改。请大家调试完成后再进行测试!
下载地址:https://download.csdn.net/download/javabuilt/10291183
此代码只是一个原理的DEMO,实际应用需要根据实际情况做相应的调整!
---------------------
本文原来是我在CSDN上写的,现在搬过来。
作者:JavaBuilt
来源:CSDN
原文:https://blog.csdn.net/JavaBuilt/article/details/79583921
版权声明:本文为博主原创文章,转载请附上博文链接!
Java防止文件被篡改之文件校验和的更多相关文章
- 从Java文件到字节码文件
本文涉及的javac编译器来自openjdk. javac的目录地址为:解压目录/langtools/src/share/classes/com/sun/tools/javac/ javac编译器将J ...
- 从java文件和CS文件里查询方法使用次数工具
前几天,领导让我找一下老系统(Java)里getRemoteUser方法都哪个文件用了,package是什么,方法被调用了多少次,当时因为着急,所以,直接人工找的,但是以后要是再出现,人工找就太讨厌了 ...
- java中的文件读取和文件写出:如何从一个文件中获取内容以及如何向一个文件中写入内容
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...
- 使用java读取文件夹中文件的行数
使用java统计某文件夹下所有文件的行数 经理突然交代一个任务:要求统计某个文件夹下所有文件的行数.在网上查了一个多小时没有解决.后来心里不爽就决定自己写一个java类用来统计文件的行数,于是花了两个 ...
- Java 基础【13】 文件(文件夹) 创建和删除
使用 java.io.file 创建文件(文件夹),算是 java 最基础的知识,但实战项目中还是需要知晓细节. 比如 File 类中的 mkdir() 和 mkdirs() 的区别. JDK API ...
- java调用sqlldr导入csv文件数据到临时表
package cn.com.file;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File; ...
- Java 实现文件上传、下载、打包、文件copy、文件夹copy。
文件and文件夹copy package org.test; import java.io.*; public class FileCopy { /** * 复制单个文件 * * @param old ...
- Java生成和操作Excel文件(转载)
Java生成和操作Excel文件 JAVA EXCEL API:是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该A ...
- Java读取Level-1行情dbf文件极致优化(3)
最近架构一个项目,实现行情的接入和分发,需要达到极致的低时延特性,这对于证券系统是非常重要的.接入的行情源是可以配置,既可以是Level-1,也可以是Level-2或其他第三方的源.虽然Level-1 ...
随机推荐
- codeforces 1262D Optimal Subsequences 主席树询问第k小
题意 给定长度为\(n\)的序列\(a\),以及m个询问\(<k,pos>\),每次询问满足下列条件的子序列中第\(pos\)位的值为多少. 子序列长度为\(k\) 序列和是所有长度为\( ...
- SpringBoot整合Quartz及log4j实例
SpringBoot整合Quartz及log4j实例 因为之前项目中经常会做一些定时Job的东西,所以在此记录一下,目前项目中已经使用elastic-job,这个能相对比Quartz更加简单方便一些, ...
- Mybatis源码学习第七天(插件源码分析)
为了不把开发和源码分析混淆,决定分开写; 接下来分析一下插件的源码,说道这里老套路先说一个设计模式,他就是责任链模式 责任链模式:就是把一件工作分别经过链上的各个节点,让这些节点依次处理这个工作,和装 ...
- Zabbix Agent升级
最近对Zabbix Server进行了升级,所以陆陆续续对Zabbix Agent也做了升级,下面是这几天工作的一个小结,鉴于经验有限和认知有限等各方面因素,下文很难面面俱到,如有疏漏或不足之处, ...
- 使用zabbix监控sql server的发布订阅
(一)背景 个人在使用sql server时,用到了sql server的发布订阅来做主从同步,类似MySQL的异步复制.在发布订阅环境搭建完成后,最重要的就是如何监控复制的状态了,sql serve ...
- 20190923-11Linux crond 系统定时任务 000 019
crond 服务管理 1.重新启动crond服务 [root@hadoop101 ~]# service crond restart centOS7是 systemctl restart crond ...
- ThinkPHP6.0 多应用模式 部署 Layuiadmin 单页版
TP6.0中的路由省略应用名只能用入口文件绑定应用 和 域名绑定应用,经过测试,最后得出域名绑定应用是最合适的部署方式.如果有更好的部署方案,欢迎分享.QQ:23426945 1. 下载TP6.0,引 ...
- Windows docker镜像文件无法删除
最近刚开始玩docker,下载镜像之前没有修改docker的保存路径,因此默认存在了c:\programdata下面,导致C盘空间不足. 之后修改了保存路径之后( docker engin里加&quo ...
- k8s重要概念及部署k8s集群(一)
k8s介绍 Kubernetes(k8s)是Google开源的容器集群管理系统(谷歌内部:Borg).在Docker技术的基础上,为容器化的应用提供部署运行.资源调度.服务发现和动态伸缩等一系列完整功 ...
- outh2
之前做天猫精灵对接,就碰到了outh鉴权,当时实现好之后没有细细缕,今天看了一个博主的介绍,贴一下 转载自http://www.ruanyifeng.com/blog/2014/05/oauth_2_ ...