Java防止文件被篡改之文件校驗功能的實例代碼
1.為什么要防止文件被篡改?
答案是顯然的,為了保證版權(quán),系統(tǒng)安全性等。之前公司開發(fā)一個系統(tǒng),技術(shù)核心是一個科學(xué)院院士的研究成果,作為一款商業(yè)軟件來說,保證公司及作者版權(quán)是非常重要的。系統(tǒng)安全性就更不用說了,系統(tǒng)兩三下就被搞垮了,那這個系統(tǒng)就不算是一個合格的系統(tǒng)。
2.文件校驗和作用
我們都知道,一個系統(tǒng)或者軟件都是由眾多文件組成的。文件校驗和的作用就是保證系統(tǒng)版本的正確性和唯一性。具體原理下面會詳細解釋。
3.文件校驗和的原理
思路和實現(xiàn)的方式可能多種多樣,我說的是自己的思路和實現(xiàn)方式,請讀者自己斟酌使用。
原理:主要有兩個核心:
1.每個不同的文件的md5值是不同的
2.每個文件被修改后的md5會發(fā)生改變
4.實現(xiàn)思路
1. 拿到系統(tǒng)的根目錄
2. 采用遞歸,遍歷目錄文件
3. 計算每個文件的md5值 , 并相加。 原因:每個文件md5值不同,相加后的md5值也必定是唯一。 一個md5值占32位,4個字節(jié)。大家都知道,1GB = 1024MB ; 1MB = 1024KB; 1KB=1024B ; 1B = 8bit ; 也就是說就算系統(tǒng)有10000個文件,10000*4B/1024 = 39KB 。這個值是遠遠小于String的最大值的。String 最大值位2GB左右,本人未親自測試過,數(shù)據(jù)從網(wǎng)上得來。
4.所有文件的md5值相加后,得到一個總的md5值,并且是唯一的。
5.用戶客戶端啟動時,會先校驗文件和,若和服務(wù)器中的校驗和不一致,則判定客戶端非法,禁止其一切行為!
注意:有些文件是一值在改變的,如log日志。故這些一直在變的文件,不應(yīng)該參與文件校驗和計算
5.代碼實現(xiàn)
校驗文件
public class CheckSystemFolderSum { // 所有文件md5總和 private static String fileSum = ""; /** * 遍歷文件夾下的所有文件(遞歸) 并對每個文件計算md5值 得到所有文件的md5值之和 * @param file 軟件系統(tǒng)的根文件夾 , suffix 目錄文件后綴(以該后綴結(jié)尾的目錄不會遍歷和計算md5值) * @return 系統(tǒng)所有文件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結(jié)尾的目錄 則計算該目錄下的文件的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) { // 若輸入的參數(shù)不是一個文件 則拋出異常 if(!file.isFile()){ throw new NumberFormatException("參數(shù)錯誤!請輸入校準文件。"); } // 定義相關(guān)變量 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值 }
測試
測試結(jié)果沒有問題。
源碼下載: 請注意,源碼文件的包名涉及隱私已被去除,還有代碼中的地址等需修改。請大家調(diào)試完成后再進行測試!
下載地址:http://xiazai.jb51.net/201811/yuanma/src-java.rar
此代碼只是一個原理的DEMO,實際應(yīng)用需要根據(jù)實際情況做相應(yīng)的調(diào)整!
總結(jié)
以上所述是小編給大家介紹的Java防止文件被篡改之文件校驗功能的實例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
Java實現(xiàn)添加、驗證PDF數(shù)字簽名的方法示例
在設(shè)置文檔內(nèi)容保護的方法中,除了對文檔加密、添加水印外,應(yīng)用數(shù)字簽名也是一種有效防偽手段。本文就使用Java實現(xiàn)添加、驗證PDF數(shù)字簽名,感興趣的可以了解一下2021-07-07Java Lambda表達式與匿名內(nèi)部類的聯(lián)系和區(qū)別實例分析
這篇文章主要介紹了Java Lambda表達式與匿名內(nèi)部類的聯(lián)系和區(qū)別,結(jié)合實例形式分析了Java Lambda表達式與匿名內(nèi)部類功能、用法、區(qū)別及操作注意事項,需要的朋友可以參考下2019-10-10Springboot+Bootstrap實現(xiàn)增刪改查實戰(zhàn)
這篇文章主要介紹了Springboot+Bootstrap實現(xiàn)增刪改查實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Log4j關(guān)閉Spring和Hibernate日志打印方式
這篇文章主要介紹了Log4j關(guān)閉Spring和Hibernate日志打印方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12MyBatis異常java.sql.SQLSyntaxErrorException的問題解決
使用mybatis插入數(shù)據(jù)時出現(xiàn)java.sql.SQLSyntaxErrorException異常,本文就來介紹一下MyBatis異常的問題解決,具有一定的參考價值,感興趣的可以了解一下2023-08-08