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);