溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C# MD5

發(fā)布時間:2020-06-21 07:22:05 來源:網(wǎng)絡(luò) 閱讀:466 作者:Aonaufly 欄目:編程語言

MD5加密在因為具有加密的不可逆性,所以在密碼加密,以及文件驗證有很大的應(yīng)用.在密碼加密方面,如果在數(shù)據(jù)庫中保存明文密碼,將是非常危險的.如果密碼是MD5加密過得,就會安全的多

但是用MD5加密過的明文密碼,因為是不能逆向還原出明文的.好處是:DBA,開發(fā)人員最多只知道你的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();
            // 加密后是一個字節(jié)類型的數(shù)組,這里要注意編碼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>
        /// 對給定文件路徑的文件加上標簽(如果文件已經(jīng)更改,則更新配置的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中的字節(jié)內(nèi)容算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;//獲取根節(jié)點
                        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>是否加了標簽或是否標簽值與內(nèi)容值一致</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簽名文件字符數(shù)組</param>
        /// <param name="index">計算起始位置</param>
        /// <param name="count">計算終止位置</param>
        /// <returns>計算結(jié)果</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();
        }
    }
}

結(jié)果:

C# MD5

從測試代碼看出 , 我們用32位MD5加密過的密文和用64位MD5加密過的密文是完全不一樣的,這點要注意.

比如 : 你存的用戶的密碼是用32位MD5加密過的,而對比密碼卻用64位的,那就很尷尬了.


二,關(guān)于文件驗證

①,測試準備

我們先在Debug目錄放2個文件:

C# MD5

關(guān)于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>

關(guān)于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} 已經(jīng)被篡改,請小心使用", txt_path);
                }
                else
                {
                    Console.WriteLine("{0}中不存在文件{1}的MD5的配置信息,請重新生成!!!", txt_md5_conf, txt_path);
                }
            }
            Console.Read();
        }
    }
}

結(jié)果:

C# MD5

確實是 , checkmd5.xml沒有關(guān)于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中無關(guān)于txt_path文件的md5的記錄則做添加操作,如果有(①,MD5沒有改變則不作任何錯誤,②,MD5已變更改其記錄的MD5值)

注意MD5會因為txt_path文件的改變而改變

結(jié)果如下:

C# MD5

注意file為Aonaufly.xml的路徑,是path


我們不改變Aonaufly.xml的內(nèi)容,做測試 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} 已經(jīng)被篡改,請小心使用", txt_path);
                }
                else
                {
                    Console.WriteLine("{0}中不存在文件{1}的MD5的配置信息,請重新生成!!!", txt_md5_conf, txt_path);
                }
            }
             
            Console.Read();
        }
    }
}

得到結(jié)果如下:

C# MD5


而當我們修改了一個Aonaufly.xml , 如下:

C# MD5

我們還是以no.3(如上)代碼測試 . 結(jié)果如下:

C# MD5

在文件簽名的應(yīng)用中,在程序每個正式的版本中打一個MD5碼,監(jiān)聽配置文件的篡改,保證安全.

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI