MD5加密在因为具有加密的不可逆性,所以在密码加密,以及文件验证有很大的应用.在密码加密方面,如果在数据库中保存明文密码,将是非常危险的.如果密码是MD5加密过得,就会安全的多

但是用MD5加密过的明文密码,因为是不能逆向还原出明文的.好处是:DBA,开发人员最多只知道你的MD5加密过的密码,而不知道正真的密码,坏处是一旦你自己把密码忘了,那就只能通过邮件等方式更换密码了.



好了先上一段MD5的核心类:


usingSystem;usingSystem.Text;usingSystem.Security.Cryptography;usingSystem.IO;usingSystem.Xml;namespaceMD5Lib{///<summary>///MD5加密及验证///</summary>publicsealedclassMD5Helper{///<summary>///获得64位的MD5加密///</summary>///<paramname="input"></param>///<returns></returns>publicstaticstringGetMD5_64(stringinput){MD5md5=MD5.Create();//加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 byte[]s=md5.ComputeHash(Encoding.UTF8.GetBytes(input));returnConvert.ToBase64String(s);}///<summary>///获得32位的MD5加密///</summary>///<paramname="input"></param>///<returns></returns>publicstaticstringGetMD5_32(stringinput){System.Security.Cryptography.MD5md5=System.Security.Cryptography.MD5.Create();byte[]data=md5.ComputeHash(System.Text.Encoding.Default.GetBytes(input));StringBuildersb=newStringBuilder();for(inti=0;i<data.Length;i++){sb.Append(data[i].ToString("x2"));}returnsb.ToString();}///<summary>///获得16位的MD5加密///</summary>///<paramname="input"></param>///<returns></returns>publicstaticstringGetMD5_16(stringinput){returnGetMD5_32(input).Substring(8,16);}///<summary>///获得8位的MD5加密///</summary>///<paramname="input"></param>///<returns></returns>publicstaticstringGetMD5_8(stringinput){returnGetMD5_32(input).Substring(8,8);}///<summary>///获得4位的MD5加密///</summary>///<paramname="input"></param>///<returns></returns>publicstaticstringGetMD5_4(stringinput){returnGetMD5_32(input).Substring(8,4);}publicstaticstringMD5EncryptHash(Stringinput){MD5md5=newMD5CryptoServiceProvider();//theGetBytesmethodreturnsbytearrayequavalentofastringbyte[]res=md5.ComputeHash(Encoding.Default.GetBytes(input),0,input.Length);char[]temp=newchar[res.Length];//copytoachararraywhichcanbepassedtoaStringconstructorArray.Copy(res,temp,res.Length);//returntheresultasastringreturnnewString(temp);}//对文件添加MD5标签及验证#regionMD5签名验证///<summary>///对给定文件路径的文件加上标签(如果文件已经更改,则更新配置的MD5值)///</summary>///<paramname="path">要加密的文件的路径</param>///<paramname="md5_conf_path">加密的密文保存文件地址(自动生成配置)</param>///<returns>标签的值</returns>publicstaticboolAddMD5(stringpath,stringmd5_conf_path){boolIsNeed=true;if(CheckMD5(path,md5_conf_path))//已进行MD5处理IsNeed=false;try{if(IsNeed){FileStreamfsread=newFileStream(path,FileMode.Open,FileAccess.Read,FileShare.Read);byte[]md5File=newbyte[fsread.Length];fsread.Read(md5File,0,(int)fsread.Length);//将文件流读取到Buffer中fsread.Close();stringresult=MD5Buffer(md5File,0,md5File.Length);//对Buffer中的字节内容算MD5Booleanis_exist=false;XmlDocumentdoc=newXmlDocument();doc.Load(md5_conf_path);XmlNodeListnode_path=doc.SelectNodes("data/path");foreach(XmlNodeiteminnode_path){if(item.Attributes["file"].InnerText==path){is_exist=true;item.Attributes["md5"].InnerText=result;//修改file的验证码doc.Save(md5_conf_path);//保存到配置break;}}if(!is_exist){//加入MD5验证配置XmlElementroot=doc.DocumentElement;//获取根节点XmlElementtagOuter=doc.CreateElement("path");tagOuter.SetAttribute("file",path);tagOuter.SetAttribute("md5",result);root.AppendChild(tagOuter);doc.Save(md5_conf_path);//保存到配置}}}catch{returnfalse;}returntrue;}///<summary>///对给定路径的文件进行验证///</summary>///<paramname="path">md5加密的文件</param>///<paramname="md5_conf_path">加密的密文保存文件地址</param>///<returns>是否加了标签或是否标签值与内容值一致</returns>publicstaticboolCheckMD5(stringpath,stringmd5_conf_path){try{FileStreamget_file=newFileStream(path,FileMode.Open,FileAccess.Read,FileShare.Read);byte[]md5File=newbyte[get_file.Length];//读入文件get_file.Read(md5File,0,(int)get_file.Length);get_file.Close();Booleanis_exist=false;XmlDocumentdoc=newXmlDocument();doc.Load(md5_conf_path);XmlNodeListnode_path=doc.SelectNodes("data/path");stringmd5=string.Empty;foreach(XmlNodeiteminnode_path){if(item.Attributes["file"].InnerText==path){is_exist=true;md5=item.Attributes["md5"].InnerText;break;}}if(!is_exist)returnfalse;//没有配置返回falsestringresult=MD5Buffer(md5File,0,md5File.Length);//计算path的MD5值,用于与配置文件里面的MD5进行对比returnresult==md5;}catch{returnfalse;}}///<summary>///是否存在文件的MD5密码的配置///</summary>///<paramname="path">文件路径</param>///<paramname="md5_conf_path">配置路径</param>///<returns></returns>publicstaticBooleanIs_Exist(stringpath,stringmd5_conf_path){XmlDocumentdoc=newXmlDocument();doc.Load(md5_conf_path);XmlNodeListnode_path=doc.SelectNodes("data/path");foreach(XmlNodeiteminnode_path){if(item.Attributes["file"].InnerText==path){returntrue;}}returnfalse;}///<summary>///计算文件的MD5值///</summary>///<paramname="MD5File">MD5签名文件字符数组</param>///<paramname="index">计算起始位置</param>///<paramname="count">计算终止位置</param>///<returns>计算结果</returns>privatestaticstringMD5Buffer(byte[]MD5File,intindex,intcount){System.Security.Cryptography.MD5CryptoServiceProviderget_md5=newSystem.Security.Cryptography.MD5CryptoServiceProvider();byte[]hash_byte=get_md5.ComputeHash(MD5File,index,count);stringresult=System.BitConverter.ToString(hash_byte);result=result.Replace("-","");returnresult;}#endregion}}


一,先测试Password(密码)加密:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingMD5Lib;namespaceMD5Demo{classProgram{staticvoidMain(string[]args){stringmy_password="Aonaufly-%~ss";Console.WriteLine("我的密码:{0}",my_password);//使用32MD5加密stringmd5_32_miwen=MD5Helper.GetMD5_32(my_password);Console.WriteLine("对密码:{0}加密后MD5密文:{1}",my_password,md5_32_miwen);if(md5_32_miwen==MD5Helper.GetMD5_64(my_password)){Console.WriteLine("密码验证通过");}else{Console.WriteLine("密码验证未通过--32为加密和64位加密的密文是不一样的");Console.WriteLine("===========================================");if(md5_32_miwen==MD5Helper.GetMD5_32(my_password)){Console.WriteLine("密码验证通过");}}Console.Read();}}}

结果:

从测试代码看出 , 我们用32位MD5加密过的密文和用64位MD5加密过的密文是完全不一样的,这点要注意.

比如 : 你存的用户的密码是用32位MD5加密过的,而对比密码却用64位的,那就很尴尬了.


二,关于文件验证

①,测试准备

我们先在Debug目录放2个文件:

关于Aonaufly.xml(程序游戏当中进行使用) , 如下:

<?xmlversion="1.0"encoding="utf-8"?><data><imgname="offline_Settlement1"res="uiimg/res/img/offline_other/js_taitou_1.png"/><imgname="offline_Settlement2"res="uiimg/res/img/offline_other/js_taitou_2.png"/><imgname="offline_Settlement3"res="uiimg/res/img/offline_other/jjcg_ditu.png"/><imgname="offline_Settlement4"res="uiimg/res/img/offline_other/tanchuang.png"/><imgname="offline_Settlement5"res="uiimg/res/img/offline_other/lose.png"/><imgname="offline_Settlement6"res="uiimg/res/img/offline_other/win.png"/></data>

关于checkmd5.xml(用于验证程序游戏中的配置是否安全)

<?xmlversion="1.0"encoding="utf-8"?><data></data>

我们来看测试代码 no.1 , 如下:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingMD5Lib;namespaceMD5Demo{classProgram{staticvoidMain(string[]args){Console.WriteLine("MD5签名验证======================================");stringtxt_path=@"Aonaufly.xml";//测试文件(为此文件生成MD5码)stringtxt_md5_conf=@"checkmd5.xml";//所有需要生成MD5码的文件的MD5码保存在此文件中//MD5Helper.AddMD5(txt_path,txt_md5_conf);//对给定文件路径的文件加上标签-成功if(MD5Helper.CheckMD5(txt_path,txt_md5_conf)){Console.WriteLine("{0}没有被篡改,可以放心使用",txt_path);}else{if(MD5Helper.Is_Exist(txt_path,txt_md5_conf)){Console.WriteLine("{0}已经被篡改,请小心使用",txt_path);}else{Console.WriteLine("{0}中不存在文件{1}的MD5的配置信息,请重新生成!!!",txt_md5_conf,txt_path);}}Console.Read();}}}

结果:

确实是 , checkmd5.xml没有关于Aonaufly.xml的记录,如下图

好,我们记录一条Aoanufly.xml的MD5信息,代码如下: no.2

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingMD5Lib;namespaceMD5Demo{classProgram{staticvoidMain(string[]args){Console.WriteLine("MD5签名验证======================================");stringtxt_path=@"Aonaufly.xml";//测试文件(为此文件生成MD5码)stringtxt_md5_conf=@"checkmd5.xml";//所有需要生成MD5码的文件的MD5码保存在此文件中MD5Helper.AddMD5(txt_path,txt_md5_conf);Console.Read();}}}

MD5Helper.AddMD5(txt_path, txt_md5_conf);

将txt_path文件的md5码记录到txt_md5_conf文件中,注意,如txt_md5_conf中无关于txt_path文件的md5的记录则做添加操作,如果有(①,MD5没有改变则不作任何错误,②,MD5已变更改其记录的MD5值)

注意MD5会因为txt_path文件的改变而改变

结果如下:

注意file为Aonaufly.xml的路径,是path


我们不改变Aonaufly.xml的内容,做测试 no.3,如下

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingMD5Lib;namespaceMD5Demo{classProgram{staticvoidMain(string[]args){Console.WriteLine("MD5签名验证======================================");stringtxt_path=@"Aonaufly.xml";//测试文件(为此文件生成MD5码)stringtxt_md5_conf=@"checkmd5.xml";//所有需要生成MD5码的文件的MD5码保存在此文件中//MD5Helper.AddMD5(txt_path,txt_md5_conf);//对给定文件路径的文件加上标签-成功if(MD5Helper.CheckMD5(txt_path,txt_md5_conf)){Console.WriteLine("{0}没有被篡改,可以放心使用",txt_path);}else{if(MD5Helper.Is_Exist(txt_path,txt_md5_conf)){Console.WriteLine("{0}已经被篡改,请小心使用",txt_path);}else{Console.WriteLine("{0}中不存在文件{1}的MD5的配置信息,请重新生成!!!",txt_md5_conf,txt_path);}}Console.Read();}}}

得到结果如下:


而当我们修改了一个Aonaufly.xml , 如下:

我们还是以no.3(如上)代码测试 . 结果如下:

在文件签名的应用中,在程序每个正式的版本中打一个MD5码,监听配置文件的篡改,保证安全.