http://www.cnblogs.com/ugoer/category/32456.html
 http://www.z6688.com/info/47936-1.htm  
Home - Forum - Articles - Books - About
Presented in HDTV, where available.
 E-mail:

Password:

Save login? Login

Register - Forgot password?
  Search | Recent | Register

Forum => General ASP.NET => Password hashing and salting


Jump to:  Announcements Article discussions CliqueSite® NewsBlog CliqueSite®.Ads Feedback and Feature Requests General ASP.NET Known Issues Maximizing ASP.NET: Real World, Object-Oriented Development POP Forums v5.1 Installation Help POP Forums v6.0 Installation Help POP Forums v8 Running Your Forum Suggestions and Feedback Testing... Testing... v7.x Installation Help

Next Oldest | Next Newest
11/17/2005 7:32:20 PM  Link | Reply | Edit | Quote 
petela     
Location: | Joined: 1/11/2005 | Posts: 53 | Offline 
Hi,

I wrote an application which takes a username and password from text boxes, salts and hashes the password, and stores the username, password, and salt values in a database table. So far, so good.

The problem I'm having is that I cannot login using a valid username and password. Here are the methods I've created:


public bool CheckCredentials(string suppliedUsername, string suppliedPassword) // returns checkPasswordMatch

{

bool checkPasswordMatch = false;

// get database connection from config file

SqlConnection DbConnection = new SqlConnection(ConfigurationSettings.AppSettings["bridgeportConnectionString"]);;

DbConnection.Open();

// from stored procedure

SqlCommand loginCommand = new SqlCommand("GetLogin", DbConnection);

// SELECT passwordhash, passwordsalt FROM LoginInfo WHERE loginname = @loginname (from sp GetLogin)

loginCommand.CommandType = CommandType.StoredProcedure;

// create parameters

SqlParameter loginnameParam = loginCommand.Parameters.Add("@loginname", SqlDbType.VarChar, 30);

// assign values to parameters

loginnameParam.Value = suppliedUsername;

// create a DataReader

SqlDataReader loginReader = loginCommand.ExecuteReader();

if (!loginReader.Read()) // if username not found in database, return false

return false;

// get passwordhash and passwordsalt values from database corresponding to loginusername

string passwordHashValue = loginReader.GetString(0);

string passwordSaltValue = loginReader.GetString(1);

string userSuppliedPassword = suppliedPassword;

// take the loginpassword and passwordsalt values and concatenate them together

string passwordAndSaltValue = String.Concat(userSuppliedPassword, passwordSaltValue);

// hash the loginpassword and passwordsalt values

string hashedPasswordAndSaltValue = FormsAuthentication.HashPasswordForStoringInConfigFile(passwordAndSaltValue, "SHA1");

// check to see if the hashedPasswordAndSaltValue matches the passwordhash value in the database

checkPasswordMatch = hashedPasswordAndSaltValue.Equals(passwordHashValue); // returns true or false

// close the DataReader and the Database connection

loginReader.Close();

DbConnection.Close();

// return true or false

return checkPasswordMatch;

}

/////////////

public void Login(object sender, System.EventArgs e)

{

bool passwordVerified = false;

// using the supplied username and password, determine if valid combination

passwordVerified = CheckCredentials(txtUsername.Text, txtPassword.Text); // return true or false

if (passwordVerified == true) // username and password combination matches database

{

// create session and redirect valid user

Session["ValidLogin"] = true;

Response.Redirect("sitemanager.aspx");

}

else // username and password combination does not match database record

{

// write out error message

message.Text = "Invalid login. Please try again.";

}

}


The code compiles without errors, but it keeps returning the error message and never validates the user. Is there a problem with the methods? What should the web.config file look like? If i'm storing the login info in a database, do I still need forms authentication?

Thanks,

petela
 
11/19/2005 3:41:39 PM  Link | Reply | Edit | Quote 
Jeff         
Location: Cleveland, OH, USA | Joined: 8/15/2000 | Posts: 794 | Offline 
Well you'll have to fire up the debugger and see what kind of values everything is returning one line at a time.


--------------------------------------------------------------------------------

Jeff 'Jones' Putz
POP World Media, LLC
Maximizing ASP.NET
 
11/21/2005 6:25:43 PM  Link | Reply | Edit | Quote 
petela     
Location: | Joined: 1/11/2005 | Posts: 53 | Offline 
Thanks for the advice. That's exactly what I did. I hadn't used the Debugger much because I've never had this much trouble getting something to work properly. Anyway, I did finally get it to work. The problem was not in my login function, but in the code I wrote to create the salt values, and in the corresponding database table.

Thanks again for your help.

petela
 

Next Oldest | Next Newest
Forum => General ASP.NET => Password hashing and salting
Please login or register to post.
CliqueSite® POP Forums Feature UI v7.5.0
©2004, POP World Media, LLC

©2006, POP World Media, LLC. All rights reserved
Legal, privacy, terms of service


(SELECT PasswordSalt FROM aspnet_Membership WHERE UserID IN (SELECT UserID FROM aspnet_Users WHERE UserName=@UserName))

select PasswordSalt from aspnet_Membership  where UserId IN (SELECT UserID FROM aspnet_Users WHERE UserName = '123'

kiEkXjmXCeIHeYFp+e07fQ==
98AFEE4E5ED96EFA0ABE882160B732D79DC33D44
fwJOdSvrP6oE20fDt7/hx01DaD8=

目的是在后台管理员可以修改用户的密码。
已知用户名UserName,用一个Textbox得到一个新的密码newpassword。我查到一种方法说是可以实现加密 System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(newpassword, "SHA1");
我把得到的加密后的密码直接写到数据库中,得到的密码是类似:98AFEE4E5ED96EFA0ABE882160B732D79DC33D44形式的,而用vs2005自带的登陆控件CreateUser创建的用户密码格式是:fwJOdSvrP6oE20fDt7/hx01DaD8= 形式的,之后用vs2005自带的登陆控件login登录时,发现修改后的密码不能登陆。我查了很多资料上说:MembershipUser提供了GetPassword 方法,但是这是只有在加密形式设置成Clear,即密码在数据库中以明码的形式存在,才能得到密码。而ChangePassword必须要提供旧密码或者密码提示答案才可以修改。默认状态下,membership是采用SHA1的方法进行加密,然后采取一种机制,与passwordsalt进行再次加密,最后形成数据库中显示的密码。
我找了很久也不知道“采取一种机制,与passwordsalt进行再次加密”是什么机制,我怎么才能实现管理员在后台修改密码呢?
我打算登录和创建新用户还是用vs2005自带的登陆控件。
在我的web.config里面
<membership>
...
passwordFormat = "Hashed"
</membership>

public override MembershipUser CreateUser(string username,
         string password,
         string email,
         string passwordQuestion,
         string passwordAnswer,
         bool isApproved,
         object providerUserKey,
         out MembershipCreateStatus status)
{
  ValidatePasswordEventArgs args =
    new ValidatePasswordEventArgs(username, password, true);

  OnValidatingPassword(args);

  if (args.Cancel)
  {
    status = MembershipCreateStatus.InvalidPassword;
    return null;
  }


  if (RequiresUniqueEmail && GetUserNameByEmail(email) != "")
  {
    status = MembershipCreateStatus.DuplicateEmail;
    return null;
  }

  MembershipUser u = GetUser(username, false);

  if (u == null)
  {
    DateTime createDate = DateTime.Now;

    if (providerUserKey == null)
    {
      providerUserKey = Guid.NewGuid();
    }
    else
    {
      if (!(providerUserKey is Guid))
      {
        status = MembershipCreateStatus.InvalidProviderUserKey;
        return null;
      }
    }

    OdbcConnection conn = new OdbcConnection(ConnectionString);
    OdbcCommand cmd = new OdbcCommand("INSERT INTO [" + tableName + "]" +
          " (PKID, Username, Password, Email, PasswordQuestion, " +
          " PasswordAnswer, IsApproved," +
          " Comment, CreationDate, LastPasswordChangedDate, LastActivityDate," +
          " ApplicationName, IsLockedOut, LastLockedOutDate," +
          " FailedPasswordAttemptCount, FailedPasswordAttemptWindowStart, " +
          " FailedPasswordAnswerAttemptCount, FailedPasswordAnswerAttemptWindowStart)" +
          " Values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", conn);

    cmd.Parameters.Add("@PKID", OdbcType.UniqueIdentifier).Value = providerUserKey;
    cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
    cmd.Parameters.Add("@Password", OdbcType.VarChar, 255).Value = EncodePassword(password);
    cmd.Parameters.Add("@Email", OdbcType.VarChar, 128).Value = email;
    cmd.Parameters.Add("@PasswordQuestion", OdbcType.VarChar, 255).Value = passwordQuestion;
    cmd.Parameters.Add("@PasswordAnswer", OdbcType.VarChar, 255).Value = EncodePassword(passwordAnswer);
    cmd.Parameters.Add("@IsApproved", OdbcType.Bit).Value = isApproved;
    cmd.Parameters.Add("@Comment", OdbcType.VarChar, 255).Value = "";
    cmd.Parameters.Add("@CreationDate", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@LastPasswordChangedDate", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName;
    cmd.Parameters.Add("@IsLockedOut", OdbcType.Bit).Value = false;
    cmd.Parameters.Add("@LastLockedOutDate", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@FailedPasswordAttemptCount", OdbcType.Int).Value = 0;
    cmd.Parameters.Add("@FailedPasswordAttemptWindowStart", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@FailedPasswordAnswerAttemptCount", OdbcType.Int).Value = 0;
    cmd.Parameters.Add("@FailedPasswordAnswerAttemptWindowStart", OdbcType.DateTime).Value = createDate;

    try
    {
      conn.Open();

      int recAdded = cmd.ExecuteNonQuery();

      if (recAdded > 0)
      {
        status = MembershipCreateStatus.Success;
      }
      else
      {
        status = MembershipCreateStatus.UserRejected;
      }
    }
    catch (OdbcException)
    {
      // Handle exception.

      status = MembershipCreateStatus.ProviderError;
    }
    finally
    {
      conn.Close();
    }


    return GetUser(username, false);
  }
  else
  {
    status = MembershipCreateStatus.DuplicateUserName;
  }


  return null;
}
internal string encodepassword(string pass, int passwordformat, string salt);

posted on 2007-07-06 18:55  左左右右  阅读(446)  评论(0编辑  收藏  举报