Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Insider News
  4. Salted Password Hashing - Doing it Right

Salted Password Hashing - Doing it Right

Scheduled Pinned Locked Moved The Insider News
csharpsecuritytutorial
16 Posts 10 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    adriancs
    wrote on last edited by
    #1

    Salted Password Hashing - Doing it Right[^]

    If you're a web developer, you've probably had to make a user account system. The most important aspect of a user account system is how user passwords are protected. User account databases are hacked frequently, so you absolutely must do something to protect your users' passwords if your website is ever breached. The best way to protect passwords is to employ salted password hashing. This page will explain how to do it properly.

    N F B 3 Replies Last reply
    0
    • A adriancs

      Salted Password Hashing - Doing it Right[^]

      If you're a web developer, you've probably had to make a user account system. The most important aspect of a user account system is how user passwords are protected. User account databases are hacked frequently, so you absolutely must do something to protect your users' passwords if your website is ever breached. The best way to protect passwords is to employ salted password hashing. This page will explain how to do it properly.

      N Offline
      N Offline
      NormDroid
      wrote on last edited by
      #2

      Good Article :thumbsup:

      Software Kinetics - Dependable Software news

      T 1 Reply Last reply
      0
      • N NormDroid

        Good Article :thumbsup:

        Software Kinetics - Dependable Software news

        T Offline
        T Offline
        TheGreatAndPowerfulOz
        wrote on last edited by
        #3

        Great article, agreed. But he doesn't cover when to hash in a web app. If I enter a password on a webpage, shouldn't I hash the password before I send it to the server? If I retrieve the salt into the webpage from the server first and then hash the password before sending to the server, doesn't that have security implications too?

        If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams
        You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun
        Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein

        W S T 3 Replies Last reply
        0
        • T TheGreatAndPowerfulOz

          Great article, agreed. But he doesn't cover when to hash in a web app. If I enter a password on a webpage, shouldn't I hash the password before I send it to the server? If I retrieve the salt into the webpage from the server first and then hash the password before sending to the server, doesn't that have security implications too?

          If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams
          You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun
          Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein

          W Offline
          W Offline
          wout de zeeuw
          wrote on last edited by
          #4

          If the hash would be calculated at the client, then the salt is needed at the client. When logging in, the user name has to be sent to the server, and then the salt would be sent back for that user, regardless of the password. So anybody would be able to retrieve salts, which would render them useless.

          Wout

          T M 2 Replies Last reply
          0
          • W wout de zeeuw

            If the hash would be calculated at the client, then the salt is needed at the client. When logging in, the user name has to be sent to the server, and then the salt would be sent back for that user, regardless of the password. So anybody would be able to retrieve salts, which would render them useless.

            Wout

            T Offline
            T Offline
            TheGreatAndPowerfulOz
            wrote on last edited by
            #5

            Exactly my point. So, you'd need to do something else between client and server to secure the account id and password.

            If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams
            You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun
            Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein

            W 1 Reply Last reply
            0
            • T TheGreatAndPowerfulOz

              Exactly my point. So, you'd need to do something else between client and server to secure the account id and password.

              If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams
              You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun
              Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein

              W Offline
              W Offline
              wout de zeeuw
              wrote on last edited by
              #6

              Ofcourse, you need SSL to secure the password transfer. But even with SSL it wouldn't be a good idea hashing at the client because anybody could get anybody else's salt.

              Wout

              1 Reply Last reply
              0
              • W wout de zeeuw

                If the hash would be calculated at the client, then the salt is needed at the client. When logging in, the user name has to be sent to the server, and then the salt would be sent back for that user, regardless of the password. So anybody would be able to retrieve salts, which would render them useless.

                Wout

                M Offline
                M Offline
                Marco Miltenburg
                wrote on last edited by
                #7

                Salts are not meant to be secret. That's the beauty of salts. They are only used to prevent rainbow attacks and are not there for additional secrecy (as the article also mentions by the way). So it's no problem to publish the salt of every user account.

                W 1 Reply Last reply
                0
                • M Marco Miltenburg

                  Salts are not meant to be secret. That's the beauty of salts. They are only used to prevent rainbow attacks and are not there for additional secrecy (as the article also mentions by the way). So it's no problem to publish the salt of every user account.

                  W Offline
                  W Offline
                  wout de zeeuw
                  wrote on last edited by
                  #8

                  Ah yes, you are most definitely right, thanks for correcting me!

                  Wout

                  1 Reply Last reply
                  0
                  • T TheGreatAndPowerfulOz

                    Great article, agreed. But he doesn't cover when to hash in a web app. If I enter a password on a webpage, shouldn't I hash the password before I send it to the server? If I retrieve the salt into the webpage from the server first and then hash the password before sending to the server, doesn't that have security implications too?

                    If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams
                    You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun
                    Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein

                    S Offline
                    S Offline
                    Schmuli
                    wrote on last edited by
                    #9

                    The following is the response I received from the article's author, after asking the same question via email: ----- Start Email Response ----- Hi, Here's a copy-pasted email I just sent someone who asked a related question: ------ Even if you are hashing the password on the client side, you still have to hash on the server. Because if you just hash in the browser, then the hash "becomes" the password in the sense that the hash value is all an attacker needs to get in to someone's account. If a bad guy hacks into the database storing all of these values, then he'll have immediate access to every account. So regardless of what you do in the browser, you still need to hash on the server. [ the original sender was worried that looking up the salts would let an attacker test if usernames are valid without knowing the password ] Anyway, if you do hash on the client side too, you're right that you really don't want to let an attacker test if usernames are valid. Since you're still hashing on the server with a random per-user salt, it's OK to sacrifice randomness for the client-side salts. I recommend combining... 1. The username. 2. A website-specific string (e.g. the domain name). ...to make the client-side salt. It's not guaranteed to be unique (e.g. domain changes ownership), but it's very likely to be. It's good enough. Another thing to consider is that not all users have JavaScript enabled in their browser (I don't), so whatever you do, the system should fall back to emulating the JavaScript hashing on the server if the user isn't running scripts in their browser. ----- I'll add this to the FAQ or to the main article since it's very important to get right! Thanks! havoc ----- End Email Response -----

                    T 1 Reply Last reply
                    0
                    • S Schmuli

                      The following is the response I received from the article's author, after asking the same question via email: ----- Start Email Response ----- Hi, Here's a copy-pasted email I just sent someone who asked a related question: ------ Even if you are hashing the password on the client side, you still have to hash on the server. Because if you just hash in the browser, then the hash "becomes" the password in the sense that the hash value is all an attacker needs to get in to someone's account. If a bad guy hacks into the database storing all of these values, then he'll have immediate access to every account. So regardless of what you do in the browser, you still need to hash on the server. [ the original sender was worried that looking up the salts would let an attacker test if usernames are valid without knowing the password ] Anyway, if you do hash on the client side too, you're right that you really don't want to let an attacker test if usernames are valid. Since you're still hashing on the server with a random per-user salt, it's OK to sacrifice randomness for the client-side salts. I recommend combining... 1. The username. 2. A website-specific string (e.g. the domain name). ...to make the client-side salt. It's not guaranteed to be unique (e.g. domain changes ownership), but it's very likely to be. It's good enough. Another thing to consider is that not all users have JavaScript enabled in their browser (I don't), so whatever you do, the system should fall back to emulating the JavaScript hashing on the server if the user isn't running scripts in their browser. ----- I'll add this to the FAQ or to the main article since it's very important to get right! Thanks! havoc ----- End Email Response -----

                      T Offline
                      T Offline
                      TheGreatAndPowerfulOz
                      wrote on last edited by
                      #10

                      Yeah, I had already sent an email to them. It's the one he copy-pasted to you.

                      If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams
                      You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun
                      Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein

                      1 Reply Last reply
                      0
                      • A adriancs

                        Salted Password Hashing - Doing it Right[^]

                        If you're a web developer, you've probably had to make a user account system. The most important aspect of a user account system is how user passwords are protected. User account databases are hacked frequently, so you absolutely must do something to protect your users' passwords if your website is ever breached. The best way to protect passwords is to employ salted password hashing. This page will explain how to do it properly.

                        F Offline
                        F Offline
                        fickendichdu
                        wrote on last edited by
                        #11

                        We send the password salted as well as a challenge for logging into our Silverlight app.

                        1 Reply Last reply
                        0
                        • A adriancs

                          Salted Password Hashing - Doing it Right[^]

                          If you're a web developer, you've probably had to make a user account system. The most important aspect of a user account system is how user passwords are protected. User account databases are hacked frequently, so you absolutely must do something to protect your users' passwords if your website is ever breached. The best way to protect passwords is to employ salted password hashing. This page will explain how to do it properly.

                          B Offline
                          B Offline
                          bpfh
                          wrote on last edited by
                          #12

                          Hold on: To create : Take a random salt + password and hash. OK I understand. To validate : Take the random salt + password and hash and check against the stored. This does not compute... There are 2 random salts here... so 2 different hashes? Unless the salts are stored... and if your system has been pwned, your salt is pwned too.... And so back to square one...

                          T 1 Reply Last reply
                          0
                          • B bpfh

                            Hold on: To create : Take a random salt + password and hash. OK I understand. To validate : Take the random salt + password and hash and check against the stored. This does not compute... There are 2 random salts here... so 2 different hashes? Unless the salts are stored... and if your system has been pwned, your salt is pwned too.... And so back to square one...

                            T Offline
                            T Offline
                            ThatEffinIanHarrisBloke
                            wrote on last edited by
                            #13

                            "And so back to square one..." - Neggative, Salt is not a secret value, it merely serves two purposes: Purpose a) By forcing the use of a salt, we need to generate a hash table for every available salt to get passwords that are using that salt, driving up the cost of hash table creation (as rather than one table for all passwords, need one table per salt) Purpose b) By using Salt we ensure that two passwords of the same value have different hash value due to the different salts....this stops things like finding all users with hash 1e0b2ffs7 blah mc blah and tying that hash to a specific password. i hope I make sense, but if you want a .NET API to do it properly than look no further than here: http://sourceforge.net/projects/pwdtknet/[^] :)

                            B 1 Reply Last reply
                            0
                            • T TheGreatAndPowerfulOz

                              Great article, agreed. But he doesn't cover when to hash in a web app. If I enter a password on a webpage, shouldn't I hash the password before I send it to the server? If I retrieve the salt into the webpage from the server first and then hash the password before sending to the server, doesn't that have security implications too?

                              If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams
                              You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun
                              Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein

                              T Offline
                              T Offline
                              Taylor Hornby
                              wrote on last edited by
                              #14

                              Thanks for the feedback. I got a few emails about this so I added a subsection to the page explaining it. It's under the heading 'In a Web Application, always hash on the server' if you want to read it in HTML, but I'll copypaste it here so readers don't need to hunt it down. Here's what I wrote: If you are writing a web application, you might wonder where to hash. Should the password be hashed in the user's browser with JavaScript, or should it be sent to the server "in the clear" and hashed there? Even if you are hashing the user's passwords in JavaScript, you still have to hash the hashes on the server. Consider a website that hashes users' passwords in the user's browser without hashing the hashes on the server. To authenticate a user, this website will accept a hash from the browser and check if that hash exactly matches the one in the database. This seems more secure than just hashing on the server, since the users' passwords are never sent to the server, but it's not. The problem is that the client-side hash logically becomes the user's password. All the user needs to do to authenticate is tell the server the hash of their password. If a bad guy got a user's hash they could use it to authenticate to the server, without knowing the user's password! So, if the bad guy somehow steals the database of hashes from this hypothetical website, they'll have immediate access to everyone's accounts without having to guess any passwords. This isn't to say that you shouldn't hash in the browser, but if you do, you absolutely have to hash on the server too. Hashing in the browser is certainly a good idea, but consider the following points for your implementation: - Client-side password hashing is not a substitute for HTTPS (SSL/TLS). If the connection between the browser and the server is insecure, a man-in-the-middle can modify the JavaScript code as it is downloaded to remove the hashing functionality and get the user's password. - Some web browsers don't support JavaScript, and some users disable JavaScript in their browser. So for maximum compatibility, your app should detect whether or not the browser supports JavaScript and emulate the client-side hash on the server if it doesn't. - You need to salt the client-side hashes too. The obvious solution is to make the client-side script ask the server for the user's salt. Don't do that, because it lets the bad guys check if a username is valid without knowing the password. Since you're hashing and salting (with a good salt) on the server

                              1 Reply Last reply
                              0
                              • T ThatEffinIanHarrisBloke

                                "And so back to square one..." - Neggative, Salt is not a secret value, it merely serves two purposes: Purpose a) By forcing the use of a salt, we need to generate a hash table for every available salt to get passwords that are using that salt, driving up the cost of hash table creation (as rather than one table for all passwords, need one table per salt) Purpose b) By using Salt we ensure that two passwords of the same value have different hash value due to the different salts....this stops things like finding all users with hash 1e0b2ffs7 blah mc blah and tying that hash to a specific password. i hope I make sense, but if you want a .NET API to do it properly than look no further than here: http://sourceforge.net/projects/pwdtknet/[^] :)

                                B Offline
                                B Offline
                                bpfh
                                wrote on last edited by
                                #15

                                Hi, This I understand. What I mean is this: If each salt is unique, your passwords will never match as between generation and comparison, they will have to be different! In very simplified pseudocode: Making the salted password

                                $salt = generateRandomSalt();
                                //The function returned 159
                                $pwd = md5('password');
                                //$pwd = 12345678901234567890123456789012
                                writeToDb($salt + $pwd);

                                Checking the salted password:

                                $salt = generateRandomSalt();
                                //This time the function returned 246
                                $pwd = md5('password');
                                //$pwd = 12345678901234567890123456789012

                                //compare
                                //12312345678901234567890123456789012 and
                                //24612345678901234567890123456789012
                                //Not looking good...

                                if(($salt + $pwd) == getStoredPasswordFromDB()) then
                                win();
                                else
                                fail();
                                endif

                                As the generated salt will always be random, the salt will always be different for each call, so... if both passwords are different, how do you validate it? In this example with a random salt, the checking condition will always fail, and if you store the salt (or even store the method of generating a unique salt per user), then you are pwned just as bad, it will just take some extra time to reverse engineer the login system, and from there, back to some form of rainbow tables once the salt part is understood and removed. Can someone light my candle here? My area of expertise is PHP along with Classic VB & VBA, so a .NET library is not much use, but really, it's the idea of just how this really works, as I am already sold on the need of such a system! Cheers!

                                T 1 Reply Last reply
                                0
                                • B bpfh

                                  Hi, This I understand. What I mean is this: If each salt is unique, your passwords will never match as between generation and comparison, they will have to be different! In very simplified pseudocode: Making the salted password

                                  $salt = generateRandomSalt();
                                  //The function returned 159
                                  $pwd = md5('password');
                                  //$pwd = 12345678901234567890123456789012
                                  writeToDb($salt + $pwd);

                                  Checking the salted password:

                                  $salt = generateRandomSalt();
                                  //This time the function returned 246
                                  $pwd = md5('password');
                                  //$pwd = 12345678901234567890123456789012

                                  //compare
                                  //12312345678901234567890123456789012 and
                                  //24612345678901234567890123456789012
                                  //Not looking good...

                                  if(($salt + $pwd) == getStoredPasswordFromDB()) then
                                  win();
                                  else
                                  fail();
                                  endif

                                  As the generated salt will always be random, the salt will always be different for each call, so... if both passwords are different, how do you validate it? In this example with a random salt, the checking condition will always fail, and if you store the salt (or even store the method of generating a unique salt per user), then you are pwned just as bad, it will just take some extra time to reverse engineer the login system, and from there, back to some form of rainbow tables once the salt part is understood and removed. Can someone light my candle here? My area of expertise is PHP along with Classic VB & VBA, so a .NET library is not much use, but really, it's the idea of just how this really works, as I am already sold on the need of such a system! Cheers!

                                  T Offline
                                  T Offline
                                  ThatEffinIanHarrisBloke
                                  wrote on last edited by
                                  #16

                                  G'Day, Yes you are correct you cannot just generate a new random salt at each authentication. You ONLY generate the random salt when the password is created, and the sal is indeed stored somewhere, generally in the DB with the Hash. Now what you are saying is if the DB is compromised and the attacker gains your hash and your salt you suggest that they are pwned and can then use the salt to generate a hash table. Now you are correct that the salt can be used to generate a hash table however that is why simply salt + hashing is not good enough. You also need to implement key stretching. The point of key stretching as per PBKDF2, Bcrypt etc, is such that generating said hash table takes an INFEASIBLE amount of time. It does this by performing a hash function such as HMACSHA1 over x (supplied) number of times and XORing the result of each pass with the previous one. If each hash generation takes half a second, it would take 1 second to generate two hashes! Making hash table generation not a viable option. So basically it is fine for the attacker to gain your salt, hell give it to them if they ask for it even....you should always assume your salt is known anyway!!! So folks always remember salt + password -> Key Stretching Function -> hash output to store. I think the provided article does a better attempt at explaining than me but I hope I make sense anyhow :) Cheers, Ian

                                  1 Reply Last reply
                                  0
                                  Reply
                                  • Reply as topic
                                  Log in to reply
                                  • Oldest to Newest
                                  • Newest to Oldest
                                  • Most Votes


                                  • Login

                                  • Don't have an account? Register

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • World
                                  • Users
                                  • Groups