none
验证MD5密码 RRS feed

  • 问题

  • MD5密码验证,sql字段是binary类型,以下代码无法读出密码?
            private void certificateps()
            {
    
                string StrConnection = ConfigurationSettings.AppSettings["connectionString"].ToString();
                SqlConnection con = new SqlConnection(StrConnection);
                con.Open();
    
                string strSql = "select convert(nvarchar,UserPassword) as 'UserPassword' from UserTable where UserName ='" + User_TextBox.Text.Trim() + "'";
                SqlDataAdapter sdr = new SqlDataAdapter(strSql, con);
                DataSet ds = new DataSet();
                sdr.Fill(ds);
    
                string Getps = ds.Tables[0].Rows[0][0].ToString();
    
                if (Getps == CommonTool.GetMD5(ps_TextBox.Text.Trim()).ToString())
                {
                    ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "alt1", "alert('" + Getps + "成功!" + "');", true);
                }
                else
                {
                    ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "alt1", "alert('" + Getps + "失败!" + "');", true);
    
                }
                con.Close();
            }
            public static byte[] GetMD5(string md)
            {
                MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
                var ret = provider.ComputeHash(Encoding.Default.GetBytes(md));
                return ret;
            }
    2009年8月24日 5:09

答案

  • 您好,我个人处理密码加密时,都是将加密后返回的字符串存入varchar类型字段。
    您的处理方式增加了复杂度,一定要这么操作。估计要将ds.Tables[0].Rows[0][0].ToString();改成读二进制的方法。
    • 已标记为答案 lfj0912 2009年8月24日 23:48
    2009年8月24日 6:06
    版主
  • <%@ Page Language="C#" AutoEventWireup="true"%>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Security.Cryptography" %>
    
    <!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>
        <script runat="server">
            protected void Page_Load(object sender, EventArgs e)
            {
                // 假定帐号表如下
                // CREATE TABLE Account (
                //    AccountKey UNIQUEIDENTIFIER NOT NULL
                //  , Account NVARCHAR(50) NOT NULL
                //  , Password NVARCHAR(36) NOT NULL
                //  , PRIMARY KEY ( AccountKey ) 
                // )
                
                // 添加一个帐号
                // this.AddAccount("XXY", "123456");
                
                bool fIsRight1 = this.VerifyAccount("XXY", "123456");
                bool fIsRight2 = this.VerifyAccount("XXY", "555555");
                
                Response.Write(String.Format("fIsRight1:{0}</br>", fIsRight1)); // 用户密码正确
                Response.Write(String.Format("fIsRight2:{0}</br>", fIsRight2)); // 用户密码不正确
            }
            
            /// <summary>
            /// 添加一个帐号
            /// </summary>
            /// <param name="fAccount">帐号</param>
            /// <param name="fPassword">密码</param>
            private void AddAccount(String fAccount, String fPassword)
            {
                using (SqlConnection conn = new SqlConnection(@"Server=XXY\SQLEXPRESS;Database=X;Integrated Security=SSPI"))
                {
                    SqlCommand comm = new SqlCommand("INSERT INTO Account (AccountKey, Account, Password)  VALUES (@AccountKey, @Account, @Password)", conn);
                    comm.Parameters.AddRange(new SqlParameter[] { 
                        new SqlParameter("@AccountKey", Guid.NewGuid()),
                        new SqlParameter("@Account", fAccount),
                        new SqlParameter("@Password", GetMd5Hash(fPassword))});
                    conn.Open();
                    comm.ExecuteNonQuery();
                }
            }
    
            /// <summary>
            /// 验证帐号密码是否正确
            /// </summary>
            /// <param name="fAccount">帐号</param>
            /// <param name="fPassword">密码</param>
            /// <returns></returns>
            private Boolean VerifyAccount(String fAccount, String fPassword)
            {
                using (System.Data.SqlClient.SqlConnection conn = new SqlConnection(@"Server=XXY\SQLEXPRESS;Database=X;Integrated Security=SSPI"))
                {
                    SqlCommand comm = new SqlCommand("SELECT COUNT(1) FROM Account WHERE Account = @Account and Password = @Password", conn);
                    comm.Parameters.AddRange(new SqlParameter[] { 
                        new SqlParameter("@Account", fAccount),
                        new SqlParameter("@Password", GetMd5Hash(fPassword))});
                    conn.Open();
                    return (Int32)comm.ExecuteScalar() == 0 ? false : true;
                }
            }
    
            /// <summary>
            /// 将指定字符串加密为MD5
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            private string GetMd5Hash(string input)
            {
                MD5 md5Hasher = MD5.Create();
                Byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
                StringBuilder sBuilder = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                    sBuilder.Append(data[i].ToString("x2"));
                return sBuilder.ToString();
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        </form>
    </body>
    </html>
    

    知识改变命运,奋斗成就人生!
    • 已标记为答案 lfj0912 2009年8月24日 23:48
    2009年8月24日 8:29
    版主

全部回复

  • 您好,我个人处理密码加密时,都是将加密后返回的字符串存入varchar类型字段。
    您的处理方式增加了复杂度,一定要这么操作。估计要将ds.Tables[0].Rows[0][0].ToString();改成读二进制的方法。
    • 已标记为答案 lfj0912 2009年8月24日 23:48
    2009年8月24日 6:06
    版主
  • 为什么把 "select convert(nvarchar,UserPassword)  改为 "select convert(varchar,UserPassword) ,就无法获取了。
    还有,获取出来的密码该怎么来比较?
    为什么Convert .ToString ( GetMD5(ps_TextBox.Text.Trim())),获取不到密码框MD5加密后的文本?


    存入数据库的加密方式也是下面的程序,下面的代码有问题吗?

            public static byte[] GetMD5(string md)
            {
                MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
                var ret = provider.ComputeHash(Encoding.Default.GetBytes(md));
                return ret;
            }
    
    • 已编辑 lfj0912 2009年8月24日 6:15
    2009年8月24日 6:11
  • 1、为什么把 "select convert(nvarchar,UserPassword)  改为 "select convert(varchar,UserPassword) ,就无法获取了。
        前者表示转为Unicode字符串,后者不是

    2、用Encoding.Unicode.GetString(GetMD5(ps_TextBox.Text.Trim()))方法把加密的字符串存入数据。密码字段设为nvarchar
        因MD5算法不可逆,所以验证时,从文本框中取出用户输入的密码加密,然后取出数据库中已加密的字符串,进行比较。
    2009年8月24日 6:31
    版主
  • <%@ Page Language="C#" AutoEventWireup="true"%>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Security.Cryptography" %>
    
    <!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>
        <script runat="server">
            protected void Page_Load(object sender, EventArgs e)
            {
                // 假定帐号表如下
                // CREATE TABLE Account (
                //    AccountKey UNIQUEIDENTIFIER NOT NULL
                //  , Account NVARCHAR(50) NOT NULL
                //  , Password NVARCHAR(36) NOT NULL
                //  , PRIMARY KEY ( AccountKey ) 
                // )
                
                // 添加一个帐号
                // this.AddAccount("XXY", "123456");
                
                bool fIsRight1 = this.VerifyAccount("XXY", "123456");
                bool fIsRight2 = this.VerifyAccount("XXY", "555555");
                
                Response.Write(String.Format("fIsRight1:{0}</br>", fIsRight1)); // 用户密码正确
                Response.Write(String.Format("fIsRight2:{0}</br>", fIsRight2)); // 用户密码不正确
            }
            
            /// <summary>
            /// 添加一个帐号
            /// </summary>
            /// <param name="fAccount">帐号</param>
            /// <param name="fPassword">密码</param>
            private void AddAccount(String fAccount, String fPassword)
            {
                using (SqlConnection conn = new SqlConnection(@"Server=XXY\SQLEXPRESS;Database=X;Integrated Security=SSPI"))
                {
                    SqlCommand comm = new SqlCommand("INSERT INTO Account (AccountKey, Account, Password)  VALUES (@AccountKey, @Account, @Password)", conn);
                    comm.Parameters.AddRange(new SqlParameter[] { 
                        new SqlParameter("@AccountKey", Guid.NewGuid()),
                        new SqlParameter("@Account", fAccount),
                        new SqlParameter("@Password", GetMd5Hash(fPassword))});
                    conn.Open();
                    comm.ExecuteNonQuery();
                }
            }
    
            /// <summary>
            /// 验证帐号密码是否正确
            /// </summary>
            /// <param name="fAccount">帐号</param>
            /// <param name="fPassword">密码</param>
            /// <returns></returns>
            private Boolean VerifyAccount(String fAccount, String fPassword)
            {
                using (System.Data.SqlClient.SqlConnection conn = new SqlConnection(@"Server=XXY\SQLEXPRESS;Database=X;Integrated Security=SSPI"))
                {
                    SqlCommand comm = new SqlCommand("SELECT COUNT(1) FROM Account WHERE Account = @Account and Password = @Password", conn);
                    comm.Parameters.AddRange(new SqlParameter[] { 
                        new SqlParameter("@Account", fAccount),
                        new SqlParameter("@Password", GetMd5Hash(fPassword))});
                    conn.Open();
                    return (Int32)comm.ExecuteScalar() == 0 ? false : true;
                }
            }
    
            /// <summary>
            /// 将指定字符串加密为MD5
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            private string GetMd5Hash(string input)
            {
                MD5 md5Hasher = MD5.Create();
                Byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
                StringBuilder sBuilder = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                    sBuilder.Append(data[i].ToString("x2"));
                return sBuilder.ToString();
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        </form>
    </body>
    </html>
    

    知识改变命运,奋斗成就人生!
    • 已标记为答案 lfj0912 2009年8月24日 23:48
    2009年8月24日 8:29
    版主