今天介绍一种MD5的加密方法,代码中写了比较详细的注释,直接上例子了。
前台代码 <% @ Page Language = " C# " AutoEventWireup = " true " CodeFile = " Encrypt.aspx.cs " Inherits = " Encrypt " %> <! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Transitional//EN " " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " > < html xmlns = " http://www.w3.org/1999/xhtml " > < head runat = " server " > < title ></ title > </ head > < body > < form id = " form1 " runat = " server " > < div > 原始密码: & nbsp; & nbsp; & nbsp; < asp:TextBox ID = " txtOriginal " runat = " server " Width = " 260px " ></ asp:TextBox > < asp:Button ID = " btnEncrypt " runat = " server " Text = " 加密 " onclick = " btnEncrypt_Click " /> < asp:TextBox ID = " txtPwd1 " runat = " server " Width = " 260px " ></ asp:TextBox > < br /> 加密后密码: < asp:TextBox ID = " txtPwd2 " runat = " server " Width = " 260px " ></ asp:TextBox > < asp:Button ID = " btnCompare " runat = " server " Text = " 比较 " onclick = " btnCompare_Click " /> < asp:TextBox ID = " txtNow " runat = " server " Width = " 260px " ></ asp:TextBox > </ div > </ form > </ body > </ html >
后台代码 using System; using System.Security.Cryptography; using System.Text; public partial class Encrypt : System.Web.UI.Page{ private const int saltLength = 4 ; // 偶数,随机值的位数,4位的“盐” protected void Page_Load( object sender, EventArgs e) { } /// <summary> /// 生成要存储在数据库中的秘密 /// </summary> /// <param name="password"> 用户输入的秘密 </param> /// <returns> 生成的秘密字符串 </returns> public static string CreateDbPassword( string password) { string strSaltValue = CreateSaltValue(); // 创建随即的4位“盐” return CreateSaltedPassword(strSaltValue, CreateHashPassword(password)); // 先返回16进制哈希密码,再返回加了“盐”后的总共36位16进制哈希密码 } /// <summary> /// 比较秘密是否相同 /// </summary> /// <param name="storedPassword"> 存在数据库中的秘密 </param> /// <param name="password"> 用户提供的秘密 </param> /// <returns> 是否相同 </returns> public static bool ComparePasswords( string storedPassword, string password) { string hashPassword = CreateHashPassword(password); // 根据输入的密码创建16进制哈希密码 if (storedPassword == null || storedPassword.Length != 32 + saltLength) return false ; // 如果加密后的密码为空或者不够36位,则返回 string saltValue = storedPassword.Substring( 32 , saltLength); // 截取已加密密码的后四位,即:“盐” string saltPassword = CreateSaltedPassword(saltValue, hashPassword); // 创建加“盐”的16进制哈希密码 return (saltPassword == storedPassword); } /// <summary> /// 根据提供的秘码生成对应的Hash值 /// </summary> /// <param name="password"> 秘码 </param> /// <returns> Hash值字符串 </returns> private static string CreateHashPassword( string password) { System.Security.Cryptography.MD5 md5 = new MD5CryptoServiceProvider(); // 创建MD5抽象类, 哈希算法的所有实现均从中继承 byte [] hexHashPassword = md5.ComputeHash(Encoding.ASCII.GetBytes(password)); // 先转换密码为ASCII字节数组,然后计算指定字节数组的哈希值,哈希值是一段数据唯一且极其紧凑的数值表示形式 string strHashPaword = HexToStr(hexHashPassword); // 将哈希值转换为16进制 return strHashPaword; } /// <summary> /// 把字节数组转换成对应的字符串 /// </summary> /// <param name="buf"></param> /// <returns></returns> private static string HexToStr( byte [] buf) { string aa = "" ; string sTemp = "" ; for ( int i = 0 ; i < buf.Length; i ++ ) { sTemp = System.Convert.ToString(buf[i], 16 ); // 将字节数组转换为16进制 aa += sTemp.PadLeft( 2 , ' 0 ' ); // 转换后的16进制为两位,若不够则左边补零 } return aa; } /// <summary> /// 生成随机值 字符串 /// </summary> /// <returns></returns> private static string CreateSaltValue() { RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); // 使用加密服务提供程序 (CSP) 提供的实现来实现加密随机数生成器 (RNG)。此类不能继承。 byte [] saltValue = new byte [saltLength / 2 ]; // 创建字节数组 rng.GetBytes(saltValue); // 生成随即数,赋值给字节数组 string strSaltValue = HexToStr(saltValue); // 转换为16进制 return strSaltValue; } /// <summary> /// 生成带有随机值的密码 /// </summary> /// <param name="saltValue"> 随机值 </param> /// <param name="hashPassword"> 秘密的Hash值 </param> /// <returns> 带有随机值的密码字符串 </returns> private static string CreateSaltedPassword( string saltValue, string hashPassword) { System.Security.Cryptography.MD5 md5 = new MD5CryptoServiceProvider(); // 创建MD5抽象类, 哈希算法的所有实现均从中继承 string tempPassword = hashPassword + saltValue; // 经过加密后的密码再加上“盐” byte [] hexSaltPassword = md5.ComputeHash(Encoding.ASCII.GetBytes(tempPassword)); // 将加了盐密码先转换密码为ASCII字节数组,然后计算指定字节数组的哈希值,哈希值是一段数据唯一且极其紧凑的数值表示形式 string strSaltPassword = HexToStr(hexSaltPassword); // 将加了盐的哈希密码转换为16进制 string dbPassword = strSaltPassword + saltValue; // 再将密码再加上“盐”,此时密码长度为36位,至此加密完成 return dbPassword; } /// <summary> /// 加密按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnEncrypt_Click( object sender, EventArgs e) { string pwd = txtOriginal.Text.Trim(); // 这里的字符串没有经过太多处理,只是测试 txtPwd1.Text = CreateDbPassword(pwd); // 调用加密函数 } /// <summary> /// 比较按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnCompare_Click( object sender, EventArgs e) { bool isTrue; isTrue = ComparePasswords(txtPwd2.Text.Trim(), txtOriginal.Text.Trim()); // 判断加密后的密码,与原始密码加密后是否相等 txtNow.Text = isTrue ? " 相等 " : " 不相等 " ; }}
运行结果:
如有不足之处,请大家补充;若有其他的好的办法,也希望大家踊跃讨论!
posted on 2010-07-16 17:41 Johnny_Z 阅读( ...) 评论( ...) 编辑 收藏转载于:https://www.cnblogs.com/Johnny_Z/archive/2010/07/16/1779101.html
相关资源:Python字符串hashlib加密模块使用案例