答案是顯然的,為了保證版權,系統安全性等。之前公司開發一個系統,技術核心是一個科學院院士的研究成果,作為一款商業軟件來說,保證公司及作者版權是非常重要的。系統安全性就更不用說了,系統兩三下就被搞垮了,那這個系統就不算是一個合格的系統。
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