文件的散列与校验:.NET发现之旅(五)

如何保障文档在互联网传输过程中的安全性不是这一节讨论的内容,我们要讨论的内容是如何验证文档的完整性。记得08年我接手绵阳九院的一个MOSS项目,由于对方单位知识的保密性,平时电脑启动就需要U盘解密,所以当时接管负责这个项目的时候,对方首先要求凡是通过网络传输的文档,必须提供MD5验证,所以当时就顺手写了这个工具FileChecker,今天分享给大家。
验证数据完整性,我们常用哈希算法。关于哈希算法,无论是MD5还是SHA1,最终生成的哈希值理论上都是不可逆的,主要用于保证数据的完整性,这和对称和非对称加密不同,后者是可逆的,主要是为了防窃取。由于很多网站使用MD5加密某些数据,比如密码、权限等,引起很多黑客想方设法的穷举破解MD5值,但多半都是白费力气,运气好的时候就撞上了,但是这个运气不是每个人都有的。一个安全的哈希算法在设计时必须满足两个要求:其一是寻找两个输入得到相同的输出值在计算上是不可行的,这就是我们通常听说的抗碰撞;其二是找一个输出,能得到给定的输入在计算上是不可行的,即不可从结果推导出它的初始状态。据说王小云教授当年就是采用碰撞破解了MD5一部分,也证明了MD5不是完美的,但至今MD5是没有被破解的。
FileChecker用.NET开发,其中核心类比较简单,就不做解释了,代码如下:
 
文件的散列与校验:.NET发现之旅(五)using System; 
文件的散列与校验:.NET发现之旅(五)using System.Collections.Generic; 
文件的散列与校验:.NET发现之旅(五)using System.Text; 
文件的散列与校验:.NET发现之旅(五)using System.Security.Cryptography; 
文件的散列与校验:.NET发现之旅(五)using System.IO; 
文件的散列与校验:.NET发现之旅(五) 
文件的散列与校验:.NET发现之旅(五)namespace MyMD5Checker 
文件的散列与校验:.NET发现之旅(五)
文件的散列与校验:.NET发现之旅(五)        class MD5AndSHA1 
文件的散列与校验:.NET发现之旅(五)        { 
文件的散列与校验:.NET发现之旅(五)                /// <summary> 
文件的散列与校验:.NET发现之旅(五)                /// 用MD5散列文件 
文件的散列与校验:.NET发现之旅(五)                /// </summary> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="curFileName">要散列的文件(全路径)</param> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="flag">散列值是否使用"-"符号,为true时使用</param> 
文件的散列与校验:.NET发现之旅(五)                /// <returns></returns> 
文件的散列与校验:.NET发现之旅(五)                ///    
文件的散列与校验:.NET发现之旅(五)                public string MD5File(string curFileName,bool flag) 
文件的散列与校验:.NET发现之旅(五)                { 
文件的散列与校验:.NET发现之旅(五)                        return HashFile(curFileName, "md5",flag); 
文件的散列与校验:.NET发现之旅(五)                } 
文件的散列与校验:.NET发现之旅(五) 
文件的散列与校验:.NET发现之旅(五)                /// <summary> 
文件的散列与校验:.NET发现之旅(五)                /// 用SHA1散列文件 
文件的散列与校验:.NET发现之旅(五)                /// </summary> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="curFileName">要散被列的文件(全路径)</param> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="flag">散列值是否使用"-"符号,为true时使用</param> 
文件的散列与校验:.NET发现之旅(五)                /// <returns></returns> 
文件的散列与校验:.NET发现之旅(五)                ///    
文件的散列与校验:.NET发现之旅(五)                public string SHA1File(string curFileName,bool flag) 
文件的散列与校验:.NET发现之旅(五)                { 
文件的散列与校验:.NET发现之旅(五)                        return HashFile(curFileName, "sha1",flag); 
文件的散列与校验:.NET发现之旅(五)                } 
文件的散列与校验:.NET发现之旅(五) 
文件的散列与校验:.NET发现之旅(五)                /// <summary> 
文件的散列与校验:.NET发现之旅(五)                /// 散列文件 
文件的散列与校验:.NET发现之旅(五)                /// </summary> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="curFileName">要被散列的文件(全路径)</param> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="algName">所用的散列算法名字,例如MD5,SHA1</param> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="flag">散列值是否使用"-"符号,为true时使用</param> 
文件的散列与校验:.NET发现之旅(五)                /// <returns></returns> 
文件的散列与校验:.NET发现之旅(五)                private string HashFile(string curFileName, string algName,bool flag) 
文件的散列与校验:.NET发现之旅(五)                { 
文件的散列与校验:.NET发现之旅(五)                        if (!System.IO.File.Exists(curFileName)) 
文件的散列与校验:.NET发现之旅(五)                                return string.Empty; 
文件的散列与校验:.NET发现之旅(五)                        System.IO.FileStream fs = new System.IO.FileStream(curFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read); 
文件的散列与校验:.NET发现之旅(五)                        byte[] hashBytes = HashData(fs, algName); 
文件的散列与校验:.NET发现之旅(五)                        fs.Close(); 
文件的散列与校验:.NET发现之旅(五)                        return ByteArrayToHexString(hashBytes,flag); 
文件的散列与校验:.NET发现之旅(五)                } 
文件的散列与校验:.NET发现之旅(五) 
文件的散列与校验:.NET发现之旅(五)                /// <summary> 
文件的散列与校验:.NET发现之旅(五)                /// 具体的散列实现 
文件的散列与校验:.NET发现之旅(五)                /// </summary> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="stream">当前文件的流式</param> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="algName">哈希算法名</param> 
文件的散列与校验:.NET发现之旅(五)                /// <returns></returns> 
文件的散列与校验:.NET发现之旅(五)                private byte[] HashData(System.IO.Stream stream, string algName)    
文件的散列与校验:.NET发现之旅(五)                {    
文件的散列与校验:.NET发现之旅(五)                        System.Security.Cryptography.HashAlgorithm algorithm; 
文件的散列与校验:.NET发现之旅(五) 
文件的散列与校验:.NET发现之旅(五)                        if (string.Compare(algName, "sha1"true) == 0)    
文件的散列与校验:.NET发现之旅(五)                        {    
文件的散列与校验:.NET发现之旅(五)                                algorithm = System.Security.Cryptography.SHA1.Create(); 
文件的散列与校验:.NET发现之旅(五)                        }    
文件的散列与校验:.NET发现之旅(五)                        else    
文件的散列与校验:.NET发现之旅(五)                        {    
文件的散列与校验:.NET发现之旅(五)                                if (string.Compare(algName, "md5"true) != 0)    
文件的散列与校验:.NET发现之旅(五)                                {    
文件的散列与校验:.NET发现之旅(五)                                        throw new Exception("algName只能是sha1或md5");    
文件的散列与校验:.NET发现之旅(五)                                }    
文件的散列与校验:.NET发现之旅(五)                                algorithm = System.Security.Cryptography.MD5.Create(); 
文件的散列与校验:.NET发现之旅(五)                        } 
文件的散列与校验:.NET发现之旅(五)                        return algorithm.ComputeHash(stream); 
文件的散列与校验:.NET发现之旅(五)                } 
文件的散列与校验:.NET发现之旅(五) 
文件的散列与校验:.NET发现之旅(五)                /// <summary> 
文件的散列与校验:.NET发现之旅(五)                /// 调整文件散列值的返回格式 
文件的散列与校验:.NET发现之旅(五)                /// </summary> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="buf">文件散列值的二进制格式</param> 
文件的散列与校验:.NET发现之旅(五)                /// <param name="flag">散列值是否使用"-"符号,为true时使用</param> 
文件的散列与校验:.NET发现之旅(五)                /// <returns></returns> 
文件的散列与校验:.NET发现之旅(五)                private string ByteArrayToHexString(byte[] buf,bool flag)    
文件的散列与校验:.NET发现之旅(五)                { 
文件的散列与校验:.NET发现之旅(五)                        if (flag) 
文件的散列与校验:.NET发现之旅(五)                        { 
文件的散列与校验:.NET发现之旅(五)                                return BitConverter.ToString(buf); 
文件的散列与校验:.NET发现之旅(五)                        } 
文件的散列与校验:.NET发现之旅(五)                        else 
文件的散列与校验:.NET发现之旅(五)                        { 
文件的散列与校验:.NET发现之旅(五)                                return BitConverter.ToString(buf).Replace("-", "");     
文件的散列与校验:.NET发现之旅(五)                        } 
文件的散列与校验:.NET发现之旅(五)                } 
文件的散列与校验:.NET发现之旅(五)        } 
文件的散列与校验:.NET发现之旅(五)
 
FileChecker实现了用MD5和SHA1算法来散列文件和校验文件。当你在给对方传输文件之前,你先用FileChecker生成MD5和SHA1哈希值,当对方接到你的文件后,再用FileChecker验证哈希值。当然,你也可以用FileChecker校验下载的文件,只需要拿到软件提供者发布的MD5或者SHA1哈希值就OK了,很多游戏网站在下载客户端的时候,都提供了MD5校验值,便是这里所说的哈希值。FileChecker界面如下:
 
1,散列文件
 
文件的散列与校验:.NET发现之旅(五)
 
2,校验文件
 
文件的散列与校验:.NET发现之旅(五)
 
如何用就不介绍了,非常简单。
 
最后是这个软件的安装包,因为这个软件是用.NET开发的,如果你的电脑上没装.NET Framework 2.0 ,请去微软下载中心下载。只所以做安装包的时候没把.NET Framework 2.0打进来,是因为这个.NET Framework 2.0有22.4M,影响上传和下载的速度。所以请自行下载.NET Framework 2.0安装。
 
最后提供FileChecker x86和x64版本的下载。
 

附件:http://down.51cto.com/data/2353185

















本文转自terryli51CTO博客,原文链接: http://blog.51cto.com/terryli/170165,如需转载请自行联系原作者



上一篇:ORACLE备份策略(转)


下一篇:一本通 1313:【例3.5】位数问题 (递推/动态规划)