您好,登錄后才能下訂單哦!
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(); } } }
結果:
從測試代碼看出 , 我們用32位MD5加密過的密文和用64位MD5加密過的密文是完全不一樣的,這點要注意.
比如 : 你存的用戶的密碼是用32位MD5加密過的,而對比密碼卻用64位的,那就很尷尬了.
二,關于文件驗證
①,測試準備
我們先在Debug目錄放2個文件:
關于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(); } } }
結果:
確實是 , checkmd5.xml沒有關于Aonaufly.xml的記錄,如下圖
好,我們記錄一條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文件的改變而改變
結果如下:
注意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(); } } }
得到結果如下:
而當我們修改了一個Aonaufly.xml , 如下:
我們還是以no.3(如上)代碼測試 . 結果如下:
在文件簽名的應用中,在程序每個正式的版本中打一個MD5碼,監聽配置文件的篡改,保證安全.
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。