您好,登录后才能下订单哦!
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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。