温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C# MD5

发布时间:2020-06-21 07:22:05 来源:网络 阅读:467 作者:Aonaufly 栏目:编程语言

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

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



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


using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Xml;

namespace MD5Lib
{
    /// <summary>
    /// MD5加密及验证
    /// </summary>
    public sealed class MD5Helper
    {
        /// <summary>
        /// 获得64位的MD5加密
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetMD5_64(string input)
        {
            MD5 md5 = MD5.Create();
            // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 
            byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
            return Convert.ToBase64String(s);
        }
        /// <summary>
        /// 获得32位的MD5加密
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetMD5_32(string input)
        {
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] data = md5.ComputeHash(System.Text.Encoding.Default.GetBytes(input));
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sb.Append(data[i].ToString("x2"));
            }
            return sb.ToString();
        }

        /// <summary>
        /// 获得16位的MD5加密
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetMD5_16(string input)
        {
            return GetMD5_32(input).Substring(8, 16);
        }
        /// <summary>
        /// 获得8位的MD5加密
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetMD5_8(string input)
        {
            return GetMD5_32(input).Substring(8, 8);
        }
        /// <summary>
        /// 获得4位的MD5加密
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetMD5_4(string input)
        {
            return GetMD5_32(input).Substring(8, 4);
        }

        public static string MD5EncryptHash(String input)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            //the GetBytes method returns byte array equavalent of a string
            byte[] res = md5.ComputeHash(Encoding.Default.GetBytes(input), 0, input.Length);
            char[] temp = new char[res.Length];
            //copy to a char array which can be passed to a String constructor
            Array.Copy(res, temp, res.Length);
            //return the result as a string
            return new String(temp);
        }

        //对文件添加MD5标签及验证
        #region MD5签名验证
        /// <summary>
        /// 对给定文件路径的文件加上标签(如果文件已经更改,则更新配置的MD5值)
        /// </summary>
        /// <param name="path">要加密的文件的路径</param>
        /// <param name="md5_conf_path">加密的密文保存文件地址(自动生成配置)</param>
        /// <returns>标签的值</returns>
        public static bool AddMD5(string path , string md5_conf_path)
        {
            bool IsNeed = true;

            if (CheckMD5(path,md5_conf_path)) //已进行MD5处理
                IsNeed = false;

            try
            {
                if (IsNeed)
                {
                    FileStream fsread = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
                    byte[] md5File = new byte[fsread.Length];
                    fsread.Read(md5File, 0, (int)fsread.Length); // 将文件流读取到Buffer中
                    fsread.Close();

                    string result = MD5Buffer(md5File, 0, md5File.Length); // 对Buffer中的字节内容算MD5
                    Boolean is_exist = false;
                    XmlDocument doc = new XmlDocument();
                    doc.Load(md5_conf_path);
                    XmlNodeList node_path = doc.SelectNodes("data/path");
                    foreach (XmlNode item in node_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验证配置
                        XmlElement root = doc.DocumentElement;//获取根节点
                        XmlElement tagOuter = doc.CreateElement("path");
                        tagOuter.SetAttribute("file", path);
                        tagOuter.SetAttribute("md5", result);
                        root.AppendChild(tagOuter);
                        doc.Save(md5_conf_path);//保存到配置
                    }
                }
            }
            catch
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// 对给定路径的文件进行验证
        /// </summary>
        /// <param name="path">md5加密的文件</param>
        /// <param name="md5_conf_path">加密的密文保存文件地址</param>
        /// <returns>是否加了标签或是否标签值与内容值一致</returns>
        public static bool CheckMD5(string path, string md5_conf_path)
        {
            try
            {
                FileStream get_file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
                byte[] md5File = new byte[get_file.Length]; // 读入文件
                get_file.Read(md5File, 0, (int)get_file.Length);
                get_file.Close();

                Boolean is_exist = false;
                XmlDocument doc = new XmlDocument();
                doc.Load(md5_conf_path);
                XmlNodeList node_path = doc.SelectNodes("data/path");
                string md5 = string.Empty;
                foreach (XmlNode item in node_path)
                {
                    if (item.Attributes["file"].InnerText == path)
                    {
                        is_exist = true;
                        md5 = item.Attributes["md5"].InnerText;
                        break;
                    }
                }
                if (!is_exist) return false;//没有配置返回false
                string result = MD5Buffer(md5File, 0, md5File.Length);//计算path的MD5值,用于与配置文件里面的MD5进行对比
                return result == md5;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 是否存在文件的MD5密码的配置
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="md5_conf_path">配置路径</param>
        /// <returns></returns>
        public static Boolean Is_Exist(string path, string md5_conf_path)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(md5_conf_path);
            XmlNodeList node_path = doc.SelectNodes("data/path");
            foreach (XmlNode item in node_path)
            {
                if (item.Attributes["file"].InnerText == path)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 计算文件的MD5值
        /// </summary>
        /// <param name="MD5File">MD5签名文件字符数组</param>
        /// <param name="index">计算起始位置</param>
        /// <param name="count">计算终止位置</param>
        /// <returns>计算结果</returns>
        private static string MD5Buffer(byte[] MD5File, int index, int count)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider get_md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] hash_byte = get_md5.ComputeHash(MD5File, index, count);
            string result = System.BitConverter.ToString(hash_byte);

            result = result.Replace("-", "");
            return result;
        }
        #endregion
    }
}


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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MD5Lib;

namespace MD5Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            string my_password = "Aonaufly-%~ss";
            Console.WriteLine("我的密码 : {0} ", my_password);
            //使用32MD5加密
            string md5_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();
        }
    }
}

结果:

C# MD5

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

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


二,关于文件验证

①,测试准备

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

C# MD5

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

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

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

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

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MD5Lib;

namespace MD5Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("MD5签名验证======================================");
            string txt_path = @"Aonaufly.xml";//测试文件(为此文件生成MD5码)
            string txt_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();
        }
    }
}

结果:

C# MD5

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

C# MD5

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MD5Lib;

namespace MD5Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("MD5签名验证======================================");
            string txt_path = @"Aonaufly.xml";//测试文件(为此文件生成MD5码)
            string txt_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文件的改变而改变

结果如下:

C# MD5

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


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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MD5Lib;

namespace MD5Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("MD5签名验证======================================");
            string txt_path = @"Aonaufly.xml";//测试文件(为此文件生成MD5码)
            string txt_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();
        }
    }
}

得到结果如下:

C# MD5


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

C# MD5

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

C# MD5

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

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI