Jump to content

database practice

Techicolors

okay so i'm diving into some web development again, at the moment learning a web stack MySQL, React, Express, Nodejs. but i am wondering about something

 

right now i'm setting up registration and authentication. reading around it is best practice to NOT store passwords in plaintext. rather hash and salt the plaintext password, then store that in the database along with the salt pattern. apparently Nodejs has a crypto library so i am using that to hash and salt passwords. but i'm confused as to how to authenticate the user? 

Link to comment
Share on other sites

Link to post
Share on other sites

So when the user goes to log in, if you hash/salt the password they input then it should match the hashed/salted password in the database


 

Link to comment
Share on other sites

Link to post
Share on other sites

To clarify on the previous response, this is the typical process:

 

To register a new user

  • Generate a random salt (This doesn't need to be crypto-secure randomness, just whatever's easiest to generate a random number.)
  • Concatenate the salt to the end of the user's password and hash that concatenated value (Do NOT implement this yourself, use the crypto library you mentioned, and if you're able to specify an algo, something like bcrypt is best. Do NOT use MD5 or another algo used for checksums and not for encryption.)
  • Store the following values in a file for lookup later:
    • User ID/Username/some identifier
    • Plaintext salt (This is why we didn't need it to be crypto-secure random)
    • Hashed value you just made

To auth a returning user

  • Look up the values you saved upon registration
  • Concatenate the saved salt to the end of the supplied password, and hash that
  • Compare the hash value to the saved hash value. If they match, user is auth'd
Link to comment
Share on other sites

Link to post
Share on other sites

6 hours ago, kuhnertdm said:

To clarify on the previous response, this is the typical process:

 

To register a new user

  • Generate a random salt (This doesn't need to be crypto-secure randomness, just whatever's easiest to generate a random number.)
  • Concatenate the salt to the end of the user's password and hash that concatenated value (Do NOT implement this yourself, use the crypto library you mentioned, and if you're able to specify an algo, something like bcrypt is best. Do NOT use MD5 or another algo used for checksums and not for encryption.)
  • Store the following values in a file for lookup later:
    • User ID/Username/some identifier
    • Plaintext salt (This is why we didn't need it to be crypto-secure random)
    • Hashed value you just made

To auth a returning user

  • Look up the values you saved upon registration
  • Concatenate the saved salt to the end of the supplied password, and hash that
  • Compare the hash value to the saved hash value. If they match, user is auth'd

thanks!

 

bcrypt actually has a function to compare password hashes, so all i need to do is store the hashed password in the database? another is how secure is this technique? 

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Techicolors said:

so all i need to do is store the hashed password in the database?

well and the salt, unless that bcrypt compare does some magic where it can store salts per user for you

 

1 hour ago, Techicolors said:

how secure is this technique? 

Nothing is 100% secure, but with each password having its own randomized salt that is re-generated each time a new password is made, it really minimizes potential damage in the case of a breach. 

Lets say an attacker breaches your database, and gets all the hashes. If you had no salt, they could use what are called rainbow tables (which are just huge lists of hashed words that let you see what word turns into what hash for a given hashing algorithm) to simply look up the hash and find the password, and then they can authenticate as any user in that database who used a password that was in the rainbow table, potentially giving them access immediately.

 

Now let's add a static salt, so the same salt for everyone and it never changes. It's sort of similar, but since there is a salt, there wont be an existing rainbow table to map from hash to plaintext, so they would have to start generating one from scratch. This would take a long time, but weaker passwords would start to be identifiable after some time, and the longer they generate the more passwords they can crack. So given enough time, if the salt isnt changed, it ends up the same as the first case with no salt (it just took some time)

 

finally lets make it a dynamic salt, and give each user their own salt and each time you change your password the salt is changed. Now the attacker has to generate rainbow tables for only specific authentications, since salts are user specific. Plus, they have to hope they crack that password before the user changes their password, or the rainbow table they are generating will be useless since the salt will change as well.

 

As you can see, it's not IMPOSSIBLE to crack, but the difference in the first example to the last should show you have these techniques can mitigate a LOT of damage. Even in a worst case scenario (they get lucky and crack the password very quickly), they only have one persons authentication, instead of everyone. This is all AFTER they already breached your network and accessed your databases, which is why network security is also a huge factor in how secure your system is. If you make your database hard to breach, and use these techniques to mitigate breach damage, you make it really hard for malicious actors to take advantage of your system.

Gaming build:

CPU: i7-7700k (5.0ghz, 1.312v)

GPU(s): Asus Strix 1080ti OC (~2063mhz)

Memory: 32GB (4x8) DDR4 G.Skill TridentZ RGB 3000mhz

Motherboard: Asus Prime z270-AR

PSU: Seasonic Prime Titanium 850W

Cooler: Custom water loop (420mm rad + 360mm rad)

Case: Be quiet! Dark base pro 900 (silver)
Primary storage: Samsung 960 evo m.2 SSD (500gb)

Secondary storage: Samsung 850 evo SSD (250gb)

 

Server build:

OS: Ubuntu server 16.04 LTS (though will probably upgrade to 17.04 for better ryzen support)

CPU: Ryzen R7 1700x

Memory: Ballistix Sport LT 16GB

Motherboard: Asrock B350 m4 pro

PSU: Corsair CX550M

Cooler: Cooler master hyper 212 evo

Storage: 2TB WD Red x1, 128gb OCZ SSD for OS

Case: HAF 932 adv

 

Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, reniat said:

well and the salt, unless that bcrypt compare does some magic where it can store salts per user for you

apparently it can because it's able to hash both passwords with salt intact

 

so it is basically as secure as the database can be? 

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Techicolors said:

so it is basically as secure as the database can be? 

There are tons of other ways to add more security to authentication, though it's a tradeoff of complexity/user effort and security.

 

  • You can check IPs and force the user to confirm if it looks suspicious
  • You can set up multi factor authentication (MFA) which can range from a phone app, to a USB key, to a fingerprint scanner, etc.
  • You can have security questions

the list goes on. Typically adding those features also requires more effort for the user to log in. Most users don't want to have to use MFA to log into something like reddit, but they might REALLY appreciate that kind of enforcement around something like bank logins.

 

The salting method illustrated earlier in the thread is kind of like a "good starting point" for user authentication. It's secure "enough" (try to avoid thinking of any system as unbreakable) for most basic cases, though again network security and setting up database access are also huge factors in ensuring a secure system.

 

 

EDIT: also for the record, i am NOT a security professional. I'm sure there are way more things involved with infosec that I've never worked with. If you really need to make a secure system, like REALLY secure (e.g. storing PHI, financial information, basically anything that could get you in some MAJOR hot water) then you should have an actual security professional on your team.

Gaming build:

CPU: i7-7700k (5.0ghz, 1.312v)

GPU(s): Asus Strix 1080ti OC (~2063mhz)

Memory: 32GB (4x8) DDR4 G.Skill TridentZ RGB 3000mhz

Motherboard: Asus Prime z270-AR

PSU: Seasonic Prime Titanium 850W

Cooler: Custom water loop (420mm rad + 360mm rad)

Case: Be quiet! Dark base pro 900 (silver)
Primary storage: Samsung 960 evo m.2 SSD (500gb)

Secondary storage: Samsung 850 evo SSD (250gb)

 

Server build:

OS: Ubuntu server 16.04 LTS (though will probably upgrade to 17.04 for better ryzen support)

CPU: Ryzen R7 1700x

Memory: Ballistix Sport LT 16GB

Motherboard: Asrock B350 m4 pro

PSU: Corsair CX550M

Cooler: Cooler master hyper 212 evo

Storage: 2TB WD Red x1, 128gb OCZ SSD for OS

Case: HAF 932 adv

 

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×