I'm fairly new to C# and RavenDB, so please excuse my lack of understanding.
I currently have a Windows Form Application. In one of the forms, I have two text boxes and one button. These two text boxes serve as the username and password inputs and the button is obviously there so that the user can login. When the user clicks on the button, a method is called and saves the content of the two inputs in two string variables.
At the moment, in my RavenDB Database, I have created two samples of username and password.
How do I appropriately check whether the username and password given from the user exists in the database.
Any help is really appreciated.
There are two ways to answer this question.
a) You can query for multiple properties using the Linq provider
session.Query<User>().Where(user=> user.Name = username && user.Password = pass).ToList();
b) The problem with this is that this assumes that you are storing the password as plain text in the database, which you should never do.
You can see how we implemented that in RaccoonBlog's RavenDB's sample application:
https://github.com/ayende/RaccoonBlog/blob/master/src/RaccoonBlog.Web/Models/User.cs
https://github.com/ayende/RaccoonBlog/blob/master/RaccoonBlog.Web/Areas/Admin/Controllers/LoginController.cs
As a matter of good security practice you don't store passwords at all, rather you you store the password's hash.
To store your password
Read the values on the server and generate a hashcode of the password. You should use crypto functions to generate hash (such as via SHA256)
Store a document in Raven DB of type User with his username and hashed password
To check if the user with the passed credentials is in the database
Query Raven DB and look for the user with the given name and password hash.
Sample code
var user = session.Query<User>()
.Where(u => u.UserName == "Alice" && u.HashedPassword == "hashPwd");
Related
I'm currently working with Identity Server 4, at present when the user logs in I need to hash their provided password and then compare with the password stored in the database (also hashed)
After some searching, I was linked to the PasswordHasher within Identity Server to handle this:
var _hasher = new PasswordHasher<User>();
var hashpassword = _hasher.HashPassword(user, context.Password);
User is my custom class that inherits from IdentityUser, however, when checking the hashed password against the one in the database the hash is completely different, I have double checked the password and I can confirm it's correct.
Can anyone suggest why I maybe seeing a different hash compared to the one in the database?
Each time you hash a password with PasswordHasher<T>.HashPassword you will get a total different result because of the salt.
To verify such hashed salted passwords use the given method IPasswordHasher<T>.VerifyPassword.
How to convert a hashed password in text string in SQL Server 2008?
I want to know the password of user which is stored in SQL Server as hash password. How to convert hashed password to normal text?
thats generally not how it works. Password checks are done on the following principal
Password -> encryption -> saved
then when user enters a password you reencrypt it, and compare the new encrypted to the old, if its the same then you got the right password you can enter. This stops people "finding out" other peoples passwords and keeps systems secure. Which is why often brute force password cracking is needed to get into things.
If you can unencrypt it - then there was no point storing it encrypted in the first place.
you cant send a string and decrypt it, because DecryptByPassPhrase function expects a varbinary parameter.
here is a small example
declare #encrypt varbinary(200)
select #encrypt = EncryptByPassPhrase('key', 'abc' )
select #encrypt
select convert(varchar(100),DecryptByPassPhrase('key', #encrypt ))
I was just wondering how I could check (when a user is changing password after the password expires) how I could use (in WebMatrix) an if branch to ensure that the new password does not equal the previous password.
I don't think I want to check for any more password history beyond just the last password used, so as long as I can just check the previous password, I think that will be fine.
I could of course query the database and check, but as the password doesn't get stored in plain text, I know that this won't work, but I also checked on the WebSecurity methods here:
http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity(v=vs.111).aspx
and didn't find anything.
What is the best way to get this done?
Since the password is not stored in the database, there is no way for you to do this, unless you make a note of the password when the user first registers, and whenever they subsequently change it.
The irony here is that by storing the original password (even in an encrypted state), you actually reduce the security of your application.
For any who are interested, I did find a nice workaround to this question, that gets the job done just fine.
Keep in mind, though, that this will only work to check the very last password they had/have.
This is what I implemented:
First, of course, in the log-in page, among other code and after actual log-in, I have the obvious (to check if their password is over 6 months old and require change):
if(WebSecurity.GetPasswordChangedDate(username).AddMonths(6) < DateTime.UtcNow)
{
WebSecurity.Logout();
Session["gActionMessage"] = "Your password has expired. Please change your password by visiting \"Login\" then \"Change Password\"";
Session["gActionMessageDisplayed"] = "not";
Response.Redirect("~/");
}
Then, I came up with this on the "Change Password" page (actually the redirected page after email verification for password reset token, but you get the idea):
if(WebSecurity.Login(email, newPassword, false) && WebSecurity.UserExists(email) && WebSecurity.GetPasswordChangedDate(email).AddMonths(6) < DateTime.UtcNow)
{
WebSecurity.Logout();
errorMessage = "You cannot repeat your last expired password.";
}
The if branch here does three checks:
First, it effectively checks and logs them in if possible based off of what they typed in as their new password.
Secondly, it checks if the user exists (not really sure if I even need this, but whatever).
And lastly, checks to make sure that their password change date is over 6 months old (because the same page is used for "forgot password" stuff, so this just ensures that the right circumstances are met before erring in this way).
So, in short, if their new password is still sufficient to log them in (before it actually gets changed, of course), then it is a repeat and subsequently logs them out and throws the error message at them instead of changing the password. If it is not sufficient to log them in, then it can't be a repeated password, and (so long as it meets any other requirements) the password is then changed.
Hope this helps anyone, who may require a non-repeated password using WebMatrix upon password change, in the future!
Reference the System.Web.Helpers assembly,
Create a custom table called 'UserPasswordHistory' that contains stored hashed passwords in the 'Password' column with an incremented version number in the 'PasswordVersion' column, a row of which is inserted each time a user is registered or a password updated for a given user,
the following code works.
var userProfile = db.UserProfiles.First(x => x.UserId == userId);
var passwords = (userProfile.UserPasswordHistory
.OrderByDescending(x => x.PasswordVersion)
.Take(_configuration.PasswordCountBeforeReuseAllowed))
.Select(x => x.Password);
return passwords.Any(previousPassword => Crypto.VerifyHashedPassword(previousPassword, password));
To answer the question specifically asked _configuration.PasswordCountBeforeReuseAllowed would be set to 1
I am using a SqlMembershipProvider and storing my passwords as hashed. I am also keeping a history of the (hashed) passwords in another table. I want to be able to compare the password a user tries to change their password to, to their old passwords and throw an error if it was too recent. I do not seem to be able to figure out how to use the hashing functions to do this. Basically what I am looking for is a method like this:
public bool PasswordCompare(string plaintextPassword, string salt, string hashedPassword)
{
//where the salt and hashedPassword are pulled out of the aspnet_Membership table
//which are automatically generated by the provider
}
I hope this is clear, thank you.
This post has some good info. Looks like you have to:
...implement your own customized
MembershipProvider, record the
password history and encrypt the
password by your self.
SQLMembershipProvider: Comparing Hashed Passwords
I want to store data in a cookie and I am not exactly sure how I will go about it.
The data is the UserName, and Password values for the users that are logging into a website, e.g. sometime like this
UserName = bob, Password=Passw0rd1
UserName = harry, Password=BLANK
UserName = george, Password=R0jjd6s
What this means is that bob and george logged into the site and chose to have their password remembered, but harry chose for his password not to be remembered.
So on the login dialog a dropdown will be present with all the usernames in it 'bob', 'harry', 'george'. If they select the username bob the password will automatically be filled in, etc.
So how does that information need to be stored in the cookie? Like it is above, or does it have to be,
UserName1 = bob, Password1=Passw0rd1
UserName2 = harry, Password2=BLANK
UserName3 = george, Password3=R0jjd6s
Are the username and password values actually stored in the same cookie, or is each piece of data separate? Any information would be good.
As far as whether or not all information should be stored in a single cookie or multiple cookies depends on how many cookies you plan on creating and whether or not you want all the information to expire at the same time. Generally, for efficiency, you will group related data into a single cookie.
However, it is a bad practice to store passwords in a cookie, since this information would then be plain-text and easily readable by an attacker.
The following link provides some guidance on cookies and asp.net.
http://msdn.microsoft.com/en-us/library/ms178194.aspx