How to auto generate password in sql database? - asp.net

I am doing a mini project on bank account. Front end is ASP.NET and backend is SQL SERVER.
When a person creates an account, auto generated account number and password would be saved in the database and that account number and password would be sent to the email id of that user.
So that user can sign in with the provided account number and password.
So my question is how to auto generate that account number and password. I am not getting how to do that.
Hoping for the best. Thank You!

First off, allow them to create their own password and HASH that bugger. Don't email their password EVER. Email a link to reset if necessary, and expire the link shortly after sending.
Second, to generate an account number, I'd use a Guid
var accountNumber = new Guid.NewGuid();
In your database, you store the Hash version of the password, and upon login, you hash the login password and compare it against the database hash.
Also in the database, the Account number would be a UniqueIdentifier if you do choose to use a Guid.

Here is the most random way I can think of:
Select NewID() as UserName, NewID() as Password
Of course, your users aren't going to like this because it is really very long:
UserName Password
------------------------------------ ------------------------------------
F050EF1A-1D6C-4A20-991C-F6B034AEBD2E 86C8D5FC-D09E-45FF-9A4F-041239082C5E
So let's shorten it to 8 characters:
Select
SubString (Cast (NewID() as VarChar(50)), 1, 8) as UserName,
SubString (Cast (NewID() as VarChar(50)), 1, 8) as Password
This looks better:
UserName Password
-------- --------
63B1A547 D5566B8C
Since you want this to be generated when the row is saved, you probably have an INSERT statement that puts the account owner's information into the database. Modify that particular line of code to do this insert as well:
Insert Into AccountTable (UserName, Password)
Select
SubString (Cast (NewID() as VarChar(50)), 1, 8) as UserName,
SubString (Cast (NewID() as VarChar(50)), 1, 8) as Password
Of course.. since you know the account owners name, you can query back to get the owner. A much better idea is to have an identity column on the table, and use Scope_Identity to get the row you just inserted.

Related

Hashing and Salting confusion

I have read a lot about hashing and salting passwords. I know how hashing works, that is all very easy, but the thing I am confused about is salting.
If I hash and salt a password and stick it into the database, how can I check that password with the password given when a user tries to log-in. Surely because the salt is completely random, it will be near-impossible to get that salt again to be able to match the database
EXAMPLE:
//On create account.
hash(password + randomSalt) to the Database
//On log-in
hash(password + differentRandomSalt) compare to Database
You generate a random hash of a fixed length with every password you hash. Then you store that salt in combination with the computed hash into one database column.
When the user wants to login, you extract the salt-part from the database and can match the results.
Example:
var salt = GenerateSecureRandom(16) // generates e.g. 0x42552241
var saltedHash = Hash(salt + password)
Login scenario:
var saltedHash = GetSaltedHashFromDatabase()
var salt = GetFirstBytes(saltedHash) // 0x42552241
var hash = GetRemainingBytes(saltedHash) // 0x47111337
var match = IsMatch(hash, salt, userInput)
A database entry could look like this (where = is the salt and * is the hash):
0x4255224147111337
========********
For (much) more details have a look at: https://crackstation.net/hashing-security.htm
The salt is random for each different user/password combination. It's not random for the same user/password combination. If that would be the case, then you would not be able to verify the password, as you already found out. If a large enough salt is generated with a sufficiently secure random number generator then it would even be impossible to verify the password. The idea of the salt is to protect against rainbow table attacks as well as creating a different password hash for different users if the password is the same.
The salt is usually stored together with the username and password hash in the database. It could be made part of a special construct that contains the salt and the password hash or it could be stored in a separate column. Sometimes the password-hash is actually a special string containing both the salt and the hash in some kind of format (using hexadecimal or base64 encoding) that needs to be parsed, but it could also a binary value simply consisting of a statically sized salt and statically sized hash.
An example bcrypt string would be:
$2a$12$QyrjMQfjgGIb4ymtdKQXIewDBqhA3eNppF8qOrMhidnEbzNvmHqhy
which is constructed as in this SO answer.
Setup:
find user
receive & verify old + password (see below)
receive new password
generate random salt
calculate hash from password and salt
store salt & hash in database with user
Verification:
find user
receive password
retrieve salt & hash for user
calculate hash to verify from password and salt
compare and return result
Usually, for security reasons, you should try and do a time-constant compare, even if that's not really an issue for password hashing. Furthermore often no distinction is made between unknown user and wrong password, simply to avoid giving information to attackers.
It makes sense to construct your password hashing scheme in such a way that it allows for updates to the amount of iterations, hash size, hash function etc.

How to manually change password in asp.net membership?

I would like to change password in database manually, but I am not sure what exactly I need to change and which methods to use. I would change it via code but currently I have only access to db.
If you want to change the password directly through the database, you are going to need to create a new user or find an existing user that you know the password of. Then, you'll need to get the password and salt, then update the user in question with the same password and salt.
Get the user's password/salt:
SELECT
au.username, aa.ApplicationName, password, passwordformat, passwordsalt
FROM
aspnet_membership am
INNER JOIN
aspnet_users au ON (au.userid = am.userid)
INNER JOIN
aspnet_applications aa ON (au.applicationId = aa.applicationid)
WHERE
au.UserName = '[user to change password]'
Change the password:
DECLARE #changeDate DATETIME
SET #changeDate = GETDATE()
EXEC aspnet_Membership_setPassword
'applicationName',
'user',
'password',
'passwordsalt',
#changeDate,
Passwordformat
Taken from here...
See this page: https://learn.microsoft.com/en-us/aspnet/web-forms/overview/older-versions-security/admin/recovering-and-changing-passwords-cs
The code calls a stored procedure:
Like with the other methods in the Membership framework, the ResetPassword method delegates to the configured provider. The SqlMembershipProvider invokes the aspnet_Membership_ResetPassword stored procedure, passing in the user's username, the new password, and the supplied password answer, among other fields. The stored procedure ensures that the password answer matches and then updates the user's password.

How to Retrieve the password from asp.net membership provider from DB

I want to retreive users passwords from the db , I tried something like this :
SELECT password, passwordformat, passwordsalt
FROM aspnet_membership am
INNER JOIN aspnet_users au
ON (au.userid = am.userid)
INNER JOIN aspnet_applications aa
ON (au.applicationId = aa.applicationid)
WHERE au.username = 'xxxxxxxxxxx'
AND aa.ApplicationId = 'xxxxxxxxxx'
But the query returns the hashed password , Is there any way i can get the original password not the hashed one. Thnx
If it is hashed you cannot retrieve it but you can recover it. Do not invent the wheel and use e.g. PasswordRecovery Control.
UPDATE:
If you by all means want to avoid using the PasswordRecovery control and want to implement this functionality by yourself you still do not need to implement your own queries to aspnet_db. There are plenty of built in methods for most of security issues in the Membership API.
You can use something like follows to reset the password:
string username = "user";
string password = "pass#word";
MembershipUser mu = Membership.GetUser(username);
mu.ChangePassword(mu.ResetPassword(), password);
This should work in case you store hashed passwords and disable q&a. In case you want q&a be enabled you can use a workaround described here.
No you can't!!
Its a hashed not encrypted
You should not store passwords as plain text

membership.deleteuser() returning false

I am trying to delete an asp.net user from all tables.
When I call:
bool isDeleted = Membership.DeleteUser(username, true);
isDeleted is being set to false;
Is there a way to tell why it is not deleting the user?
I found another reason why the user could not be deleted:
it happens also if you change (in the aspnet_Users) the UserName but not the LoweredUserName accordingly.
At least this is what happened to me:
as soon that I changed also the LoweredUserName I could finally delete the user.
Put a break point on that line of code and press F8 to step into it in debug mode.
Unfortunately it looks like when you delete membership user, even with deleteAllRelatedData=true
e.g.
Membership.DeleteUser(UserName.Text, true);
The user is NOT deleted from the dbo.aspnet_Users table which means that user cannot then re-register with the same name again (even though they will will have a different GUID)
I understand this is intended behaviour though it makes no sense to me.
However, the following routine will remove all traces from the aspnet database
CREATE PROCEDURE [dbo].[ASPNET_Member_DELETE_By_Name]
#UserNameToDelete nvarchar(255)
AS
BEGIN
DECLARE #UserToDelete nvarchar(255)
SELECT #UserToDelete = UserID
FROM aspnet_Users WHERE UserName = #UserNameToDelete)
DELETE FROM aspnet_Profile WHERE UserID = #UserToDelete
DELETE FROM aspnet_UsersInRoles WHERE UserID = #UserToDelete
DELETE FROM aspnet_PersonalizationPerUser WHERE UserID = #UserToDelete
DELETE FROM aspnet_Membership WHERE UserID = #UserToDelete
DELETE FROM aspnet_Users WHERE UserID = #UserToDelete
END
However, this has limitations if you are using aspnet membership across several applications (as I am) with the same database - you may have a situation where the same user logs in to multiple applicatiosn with the same user name.
For this scenerio you will need to pass in the application name and determine the application ID for the user prior to performing the delete.
First time I've posted here so be gentle...
The username is probably wrong - either the name doesn't match what's in the database, or the user isn't really in the database.
However, the ApplicationName could be wrong, or you could be pointed at the wrong Membership database by mistake.
The only other possibility that I can see is that you've modified the aspnet_Users_DeleteUser sproc and broke it.
Try removing the provider name, it worked for me by sending the username only.
I'm using SharePoint 3.0 with FBA, when a user is removed from SharePoint you can still find it in the FBA database. That's why I use this function as followed:
bool deleteUserResult = Membership.DeleteUser(currentUserLogin, true);
if (!deleteUserResult) throw new Exception("...);
hope this helps,
Damien

Best database design approach to join complex data to ASP.Net Membership tables

I'm looking to use a slightly modified ASP.Net Membership Provider to handle the standard user account creation/authentication/etc in a website. We have a fair amount of legacy data that I need to migrate in order to provide continuity with our existing users' saved information (like order history, wishlist, etc). [NOTE: We have to migrate anyway, so this is not the reason we're migrating data]
I'm wondering what a sensible approach is for joining this additional data to the asp.net membership tables. There are a two unique keys that I could use on the user table - UserId or email - which we will use as a surrogate for username.
My question is, what is the better access pattern (and hence foreign key) to use elsewhere in my tables for storing orders, wishlists, etc?
In HttpContext, a User object is available that contains the "Username", our email address,
but doesn't have the Guid for userId available.
I see 3 options:
I'd like to simply use the uniqueidentifier UserId for efficiency of access over a lengthy varchar email address, but it doesn't appear readily available without extra database calls to fetch it via email/login. Is there some way to get the UserId so I can make it the foreign key on different tables?
I can pass in email address (username) as the input parameter, join on userId where email address = #emailAddress, and use userId as the foreign key on other tables.
Not viable
I can store username/email address on all the other tables as a foreign key - which would be an unfortunate denormalization
Any thoughts on a best method from either a DB perspective or from an application efficiency perspective?
You can get UserId:
MembershipUser myObject = Membership.GetUser();
string UserID = myObject.ProviderUserKey.ToString();
or maybe (please, check it)
string userId = Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString();

Resources