MD5加密在因为具有加密的不可逆性,所以在密码加密,以及文件验证有很大的应用.在密码加密方面,如果在数据库中保存明文密码,将是非常危险的.如果密码是MD5加密过得,就会安全的多
夏河ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联建站的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18982081108(备注:SSL证书合作)期待与您的合作!
但是用MD5加密过的明文密码,因为是不能逆向还原出明文的.好处是:DBA,开发人员最多只知道你的MD5加密过的密码,而不知道正真的密码,坏处是一旦你自己把密码忘了,那就只能通过邮件等方式更换密码了.
好了先上一段MD5的核心类:
using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Xml;
namespace MD5Lib
{
///
/// MD5加密及验证
///
public sealed class MD5Helper
{
///
/// 获得64位的MD5加密
///
///
///
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);
}
///
/// 获得32位的MD5加密
///
///
///
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();
}
///
/// 获得16位的MD5加密
///
///
///
public static string GetMD5_16(string input)
{
return GetMD5_32(input).Substring(8, 16);
}
///
/// 获得8位的MD5加密
///
///
///
public static string GetMD5_8(string input)
{
return GetMD5_32(input).Substring(8, 8);
}
///
/// 获得4位的MD5加密
///
///
///
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签名验证
///
/// 对给定文件路径的文件加上标签(如果文件已经更改,则更新配置的MD5值)
///
/// 要加密的文件的路径
/// 加密的密文保存文件地址(自动生成配置)
/// 标签的值
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;
}
///
/// 对给定路径的文件进行验证
///
/// md5加密的文件
/// 加密的密文保存文件地址
/// 是否加了标签或是否标签值与内容值一致
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;
}
}
///
/// 是否存在文件的MD5密码的配置
///
/// 文件路径
/// 配置路径
///
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;
}
///
/// 计算文件的MD5值
///
/// MD5签名文件字符数组
/// 计算起始位置
/// 计算终止位置
/// 计算结果
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(程序游戏当中进行使用) , 如下:
关于checkmd5.xml(用于验证程序游戏中的配置是否安全)
我们来看测试代码 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码,监听配置文件的篡改,保证安全.
网页标题:C#MD5
URL网址:http://www.jxjierui.cn/article/jpihij.html


咨询
建站咨询
