zoukankan      html  css  js  c++  java
  • 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
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    Linux操作篇之配置Samba
    Chrome扩展实现网页图片右键上传(以E站图片搜索为例)
    Linux开机自动挂载NFS配置的一个误区
    ffmpeg指令解读海康威视摄像头
    linux服务器性能调优之tcp/ip性能调优
    多线程程序设计中的8条简单原则
    初识文件系统
    socket中的listen到底干了哪些事情?
    ip面向无连接?TCP面向连接?HTTP连接方式?
    网络层和数据链层的区别
  • 原文地址:https://www.cnblogs.com/amazingjava/p/9956351.html
Copyright © 2011-2022 走看看