威宁热线

威宁团菜到家

[安全维护] 利用MD5加密实现网页文件防篡改系统防黑教程

[复制链接]
威宁热线 发表于 2021-2-7 23:30:24 | 显示全部楼层 |阅读模式

MD5算法概述
MD5的作用是对一段信息(message)生成信息摘(message-digest),该摘要对该信息具有唯一性,可以作为数字签名。用于验证文件的有效性(是否有丢失或损坏的数据),对用户密码的加密,在哈希函数中计算散列值。输入一个任意长度的字节串,生成一个128位的整数。由于算法的某些不可逆特征,在加密应用上有较好的安全性。并且MD5算法的使用不需要支付任何版权费用。唯一性和不可逆性都不是绝对的,从理论上分析是一种多对一的关系,但两个不同的信息产生相同摘要的概率很小。不可逆是指从输出反推输入所需的运算量和计算时间太大,使用穷搜字典的方法又需要太多的存储空间。
Web系统设计思路
本系统是基于java web,并借助strut2来实现的。基本的设计思路是通过web页面来先后两次计算系统外存中某文件的MD5值,并且进行比对,若是相同,文件没有被篡改,若是不同,则说明文件被篡改过。
Web版本文件防篡改系统详细的设计思路:通过jsp面取出系统外存中的某个需要计算的文件,jsp提交以后,通过strut2 的action带值跳转到java的逻辑层中。在逻辑层的action中调用dao方法,dao中封装了计算MD5值的方法。Dao方法中接受了jsp传过来的文件,并计算器MD5值,计算完成以后,将其值原路径返还给action,这是第一次计算文件的MD5值,将其保存在Session中,便于将其与第二次的MD5值进行比对。第一次顺利执行完以后跳转到success页面中。现在开始进行文件的第二次MD5计算,同样通过上述的方法。在计算完MD5值后,把第二次算出来的MD5值与第一次计算出来的,并且保存在session中的值进行比对,若相同,则没有变。若是不同,则说明被篡改过。
系统实现
第一步,Index.jsp中的源代码,
<!-- Index.jsp 在这里添加系统外存中的文件 -->
                <center>
                        <form action="fileCrypt" method="get">
                                <table>
                                        <tr>
                                                <td>文件名:</td>
                                                <td><input type="file" name="Md5FilesEntity.filename" />
                                                </td>
                                                <td><input type="submit" value="start" />
                                                </td>
                                        </tr>
                                </table>
                        </form>
                </center>
第二步,struts配置文件中的源代码
<!-- struts2配置文件 -->
<struts>
        <constant value="true" name="struts.devMode" />
        <constant value="zh_CN" name="struts.locale" />
        <constant value="utf-8" name="struts.i18n.encoding" />

        <package name="default" extends="struts-default">
                <action name="mdeAction" class="com.crypt.action.mdeAction"
                        method="codeCrype">
                        <result name="success">/index.jsp</result>
                </action>
                <action name="fileCrypt" class="com.crypt.action.FilesCryptAction">
                        <result name="success">/success.jsp</result>
                </action>
                <action name="fileCrypt2" class="com.crypt.action.FilesCryptAction" method="SetCrypt2">
                        <result name="success">/FilnallySuccess.jsp</result>
                        <result name="fail">/fail.jsp</result>
                </action>
</struts>   
第三步,经过struts2的跳转到FilesCryptAction
package com.crypt.action;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.crypt.dao.Md5_dao;
import com.opensymphony.xwork2.ActionSupport;
import com.crypt.entity.Md5FilesEntity;
public class FilesCryptAction extends ActionSupport {
        private Md5FilesEntity Md5FilesEntity = new Md5FilesEntity();

        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session =  request.getSession();
        public Md5FilesEntity ge***5FilesEntity() {
                return Md5FilesEntity;
        }
        public void se***5FilesEntity(Md5FilesEntity md5FilesEntity) {
                Md5FilesEntity = md5FilesEntity;
        }
        public String execute() throws IOException {
                String fileCode = null;
                try {
                        fileCode = Md5_dao.getFileCode("e:" + Md5FilesEntity.getFilename());
                        session.setAttribute("fileCode", fileCode);//将第一次算出来的MD5值暂时保存在session中
                } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                Md5FilesEntity.setFileAfterHashCode1(fileCode);
                return "success";
        }
        public String SetCrypt2() {
                String fileCode2 = null;
                try {
                        fileCode2 = Md5_dao
                                        .getFileCode("e:" + Md5FilesEntity.getFilename());
                } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                Md5FilesEntity.setFileAfterHashCode2(fileCode2);
                System.out.println("session1"+session.getAttribute("fileCode"));
                if (fileCode2 .equals(session.getAttribute("fileCode"))) {
                        return "success";
                } else {
                        return "fail";
                }
        }
}

第四步,action中开始带值跳转到Md5_dao中
package com.crypt.dao;
import com.crypt.md5.Md5Crypt_1;
import com.crypt.md5.Md5Crypt_2;
public class Md5_dao {
        public static String getFileCode(String fileName) throws Exception {
                System.out.println(fileName);
                String hashCode = Md5Crypt_1.getHash(fileName, "MD5");
                System.out.println(hashCode);
                return hashCode;
        }
}      
第五步,在系统中已经做好了一个给某文件计算其MD5值得API,所以在DAO中直接调用,现在在Md5Crypt_1这个方法中直接处理
package com.crypt.md5;
import java.io.*;
import java.security.*;
public class Md5Crypt_1 {
        public static char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7',
                        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
        public static void main(String[] args) throws Exception {
                String fileName = "e:/111.txt";
                String hashType = "MD5";
                System.out.println(hashType + " == " + getHash(fileName, hashType));
        }
        public static String getHash(String fileName, String hashType)
                        throws Exception {
                InputStream fis;
                fis = new FileInputStream(fileName);
                byte[] buffer = new byte[1024];
                MessageDigest md5 = MessageDigest.getInstance(hashType);
                int numRead = 0;
                while ((numRead = fis.read(buffer)) > 0) {
                        md5.update(buffer, 0, numRead);
                }
                fis.close();
                return toHexString(md5.digest());
        }
        public static String toHexString(byte[] b) {
                StringBuilder sb = new StringBuilder(b.length * 2);// 构造一个字符串生成器,并初始化为指定的字符串内容
                for (int i = 0; i < b.length; i++) {
                        sb.append(hexChar[(b & 0xf0) >>> 4]);// append 方法始终将这些字符添加到生成器的末端
                        sb.append(hexChar[b & 0x0f]);
                }
                return sb.toString();
        }
}
第六步,成功的计算出文件的MD5的值以后,在action中将第一次的MD5存在Session中,并且通过struts2配置文件的配置,跳转到seccess.jsp中,显示第一次计算出的MD5值,并且提示开始进行第二次计算:
Success.jsp中的源代码:
<body>
   第一次计算的md5值是:
   <s:iterator value="Md5FilesEntity" id="Md5FilesEntity" status="L">
                <s:property value="#Md5FilesEntity.fileAfterHashCode1" />
        </s:iterator>

                <center>
                        <form action="fileCrypt2" method="get">
                                <table>
                                        <tr>
                                                <td>文件名:</td>
                                                <td><input type="file" name="Md5FilesEntity.filename" />
                                                </td>
                                                <td><input type="submit" value="start" />
                                                </td>
                                        </tr>
                                </table>
                        </form>
                        <form>
                                <textarea style="text-align: left;" rows="10" cols="41"
                                        readonly="readonly">
        <s:iterator value="Md5FilesEntity" id="Md5FilesEntity" status="L">
                <s:property value="#Md5FilesEntity.Md5FileCode" />
        </s:iterator>
        </textarea>
                        </form>
                </center>
  </body>
第七步,开始进行第二次提交文件,计算其MD5值,按照上述流程再进行一次计算以后,把第二次计算出来的MD5值与第一次的值进行比对,若两次的MD5        相同的,则说明没有篡改;若两次的MD5值不同,则说明文件遭到篡改。至此整个系统就完成了。
文件防篡改系统测试
回复

使用道具 举报

我是小白 发表于 2021-2-8 00:55:05 | 显示全部楼层
莫非威宁热线都是使用MD5来防篡改的吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表