答案是显然的,为了保证版权,系统安全性等。之前公司开发一个系统,技术核心是一个科学院院士的研究成果,作为一款商业软件来说,保证公司及作者版权是非常重要的。系统安全性就更不用说了,系统两三下就被搞垮了,那这个系统就不算是一个合格的系统。
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.代码实现
校验文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
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值
}
|
测试
测试结果没有问题。
源码下载: 请注意,源码文件的包名涉及隐私已被去除,还有代码中的地址等需修改。请大家调试完成后再进行测试!
下载地址:src-java.rar
此代码只是一个原理的demo,实际应用需要根据实际情况做相应的调整!
总结
以上所述是小编给大家介绍的java防止文件被篡改之文件校验功能的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:https://www.cnblogs.com/amazingjava/archive/2018/11/14/9956351.html