[HN Gopher] We Didn't Encrypt Your Password, We Hashed It
       ___________________________________________________________________
        
       We Didn't Encrypt Your Password, We Hashed It
        
       Author : mrzool
       Score  : 125 points
       Date   : 2020-09-04 20:32 UTC (2 hours ago)
        
 (HTM) web link (www.troyhunt.com)
 (TXT) w3m dump (www.troyhunt.com)
        
       | saagarjha wrote:
       | > They're bcrypt hashes so good job there, but the fact they're
       | suggesting everyone changes their password illustrates that even
       | good hashing has its risks.
       | 
       | It's _good_ that they suggested changing passwords, though. I
       | have a feeling that if you call them out they 're going to go
       | back to "the passwords are secure because they were encrypted".
        
       | [deleted]
        
       | miles wrote:
       | This seems odd, especially coming from Troy:
       | 
       | > Take, for example, the following password:
       | 
       | > P@ssw0rd
       | 
       | > This is a good password because it has lowercase, uppercase,
       | numeric and non-alphanumeric values plus is 8 characters long.
       | 
       | Calling it a good password, even with the later caveat that
       | "hackers have worked [character substitution] out", does not seem
       | to make sense:
       | 
       | It's Time to Kill Your Eight-Character Password
       | https://www.tomsguide.com/us/8-character-password-dead,news-...
       | "Any eight-character password hashed using Microsoft's widely
       | used NTLM algorithm can now be cracked in two and a half hours."
        
         | everdrive wrote:
         | This might be a stupid question, but why doesn't Microsoft just
         | use a better hashing algorithm?
        
         | nerdponx wrote:
         | _This is a good password because it has lowercase, uppercase,
         | numeric and non-alphanumeric values plus is 8 characters long.
         | Yet somehow, your human brain looked at it and decided "no,
         | it's not a good password" because what you're seeing is merely
         | character substitution. The hackers have worked this out too
         | which is why arbitrary composition rules on websites are
         | useless._
         | 
         | Either you stopped reading 1 sentence too early, or you are
         | posting in bad faith to try and smear Troy.
        
           | srtjstjsj wrote:
           | Or Troy wrote a confusing sentence that didn't make sense.
        
         | i-am-curious wrote:
         | Won't you add a seed before hashing. With a 8 byte seed that's
         | 16 effective characters, probably impossible to crack.
        
           | kohtatsu wrote:
           | You add a salt, which is stored plaintext alongside the
           | password.
        
           | __s wrote:
           | By seed you mean salt. Salts are stored in plaintext, so they
           | don't increase the entropy of the password. Instead they make
           | it so that each password hashes uniquely so that everyone
           | with the same password gets different hashes. They also
           | mitigate rainbow tables by effectively requiring the attacker
           | to create a rainbow table per target
        
           | SloopJon wrote:
           | I'm not sure what you mean by a seed. If you mean a salt,
           | that's no more secret than the hash. It has the effect of
           | requiring you to crack each hash separately, but doesn't make
           | it any harder to crack an individual hash.
        
         | zemnmez wrote:
         | The issue here isn't so much the password strength, but the
         | algorithm used to hash the password. A good password hashing
         | algorithm like scrypt takes a long time to make a single guess,
         | even if the input is simple, and since every single password
         | has its own salt, it has to be re-calculated for every
         | password, even if all of them are 'P@ssword'.
        
           | kohtatsu wrote:
           | It's up to the site operator to tune the cost; it's generally
           | recommended 100-250ms depending on how much you're willing to
           | make your users wait.
           | 
           | FWIW there are ASICs now that will get orders of magnitude
           | faster hash throughput than your servers.
        
             | zemnmez wrote:
             | This is true, except for scrypt, which is very tough to
             | make ASICs for. As for bcrypt, it's true that ASICS can go
             | very fast, but you ultimately have a massive advantage as
             | defender here. An attacker needs to try billions of
             | combinations per hash, but you can simply take a whole
             | second of CPU time (scaled to your current load, roughly)
             | if you want -- that's not a lot for a user, but for an
             | attacker taking several billion of even half a second makes
             | cracking very hard.
        
         | ysavir wrote:
         | I took that to be a sarcastic comment on how many sites will
         | see that password and say "wow, strong password!" when it's
         | actually one of the most crackable passwords available.
        
           | blendergeek wrote:
           | This comment is definitely sarcastic. He continues:
           | 
           | > The hackers have worked this out too which is why arbitrary
           | composition rules on websites are useless.
        
         | sigzero wrote:
         | I think he was only saying it was "good" because it had those
         | elements and not because "P@ssw0rd" is a "good password".
        
           | edoceo wrote:
           | I thought so too. Good as in, example of what a good-ish
           | password might look like, not this is literally a good
           | password
        
           | kohtatsu wrote:
           | 8 characters is short, especially when all the characters are
           | directly derived from a word.
        
           | prophesi wrote:
           | Yeah I think that whole paragraph needs to be rewritten; one
           | could also come away thinking that substituting characters in
           | a word with symbols is also a "good" password.
        
         | samsgro wrote:
         | Troy is sarcastically explaining that this is a "good password"
         | according to older password complexity rules, but a horrible
         | password given predictable password substitution logic.
         | Password complexity rules accomplish little.
         | 
         | Obligatory xkcd comic link: https://xkcd.com/936/
        
       | mooreds wrote:
       | I get he's ranting about imprecise terminology, but really, what
       | does this knowledge gain the end user? Maybe I'm missing the
       | point. Users don't care if their password was hashed or encrypted
       | or stored in an ice freezer in Antarctica.
       | 
       | They care (sometimes, sometimes they don't act like it, see
       | https://www.ieee-security.org/TC/SPW2020/ConPro/papers/bhaga... )
       | that it was compromised.
       | 
       | An end user doesn't have any control or knowledge over the
       | password storage mechanism for any sites, so the best thing is to
       | use a strong random password generating password manager--because
       | that is something the end user can control.
       | 
       | However, for the websites managing passwords, I'd suggest
       | reviewing the NIST guidelines:
       | https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.S...
        
         | kop316 wrote:
         | The knowledge it gains the end user if the confidence that the
         | service I am using actually knows what they are doing. I have
         | often found that if someone uses imprecise terminology, it is a
         | symptom of a bigger issue.
        
         | staticautomatic wrote:
         | Except when you hit a website that refuses your auto-generated
         | strong random password, which happens to me with shocking
         | regularity.
        
           | bigyikes wrote:
           | Your password must contain at least one special character.
           | Except !, that isn't allowed.
        
       | laristine wrote:
       | Many comments complain how Troy explains about technical stuff
       | like encryption vs. hashing and the users don't care about or
       | understand it. However, don't forget that many readers of his
       | blog are the technologically literate and can appreciate the
       | nuances of this content. In fact, I find this particular post
       | quite easy to understand for any beginners who want to learn
       | about about password security.
       | 
       | The distinction between encryption and hashing can never get too
       | much education, both for the end users and the more technical
       | developers/sysadmins.
        
       | riazrizvi wrote:
       | Not sure if there is any merit to this article.
       | 
       | The author thinks passwords are not encrypted on Wattpad, because
       | they ask you to change passwords on other sites where you have
       | used the same password. The reason is more likely that Wattpad
       | uses a common encryption algorithm. The hackers chance of gaining
       | access to your other accounts using the same password is now much
       | higher, especially if you use a relatively easy to guess string.
       | Because using a fast computer they can run through common
       | encryption algorithms with each guess of your password at their
       | leisure... Once they have a match, they can login to your other
       | sites.
       | 
       | Also hashing is nothing like encryption. To clarify hashing, is
       | used to map very large data types to far smaller ones of just a
       | few dozen (or few thousand) character strings, for the sake of
       | speedy lookups. Hashing algorithms are not one way, you can
       | determine the possible input values used to generate the hash. In
       | the case of (relatively speaking) very small input data types
       | like passwords, there is likely a 1:1 ratio of input password to
       | hash, making it effectively a plain text password. So why would
       | anyone use it? What evidence is there to suggest Wattpad would
       | use an obviously ineffective method for encrypting passwords?
       | 
       | So the statement, "a password hash is a representation of your
       | password that can't be reversed" and other statements about the
       | security of hashing, is just incorrect - for passwords. I agree
       | that hashing is statistically 1-way for large inputs like big
       | strings or images, since then the possible inputs that match to a
       | particular hash is very very large. It is not so for small ones,
       | like passwords, where the data type is smaller/similar in size to
       | the hash range.
        
         | penagwin wrote:
         | > so why would anyone use it
         | 
         | Because once you salt it (use a different salt for each hash,
         | which solved your collision issue) and purposely slow it down
         | (through multiple rounds,etc) it effectively ruins precomputing
         | the hashes because of how many permutations there are.
         | 
         | Of course this depends on which hashing algorithm you use. Md5?
         | You can do millions a second. Bcrypt? You can make one hash
         | take 100ms, that's 10a second. They also use a random salt for
         | each hash - so precomputed hashes will only work for that hash.
         | 
         | The issues you highlighted are very real for md5, but there's a
         | reason md5 is not recommended for passwords.
        
       | zokier wrote:
       | The difference between hashing and encrypting that I did not find
       | quite spelled out enough in the article is that with leaked
       | hashes there is a risk of cracking _proportional to the password
       | strength_. High entropy passwords will not get cracked even if
       | they are hashed with the MD5 which pretty much represents worst
       | case scenario[1]. With encryption, it is very much all or nothing
       | scenario; if the database gets cracked then all of the passwords
       | get revealed.
       | 
       | [1] Napkin math: Single Titan RTX does some 65GH/s of MD5, so if
       | you have 80bit password it would take in the order of 2^80/65e9
       | seconds = 500e3 gpu-years to crack
        
       | UnicycleSkewer wrote:
       | I wonder why it isn't best practice to hash with a salt and then
       | encrypt the passwords using something like AES. The encryption
       | key can be stored in the secrets manager and be injected via
       | environment variables.
       | 
       | Unlike a pepper it is possible to change the encryption key if it
       | is leaked. I don't think changing a pepper for existing hashes is
       | possible, but if they are encrypted you can just reencrypt them
       | with the new key.
       | 
       | So is there an obvious downside I'm not seeing to hash with a
       | salt and then encrypt?
        
         | est31 wrote:
         | I don't see any downsides. As you point out, upgrading hashed
         | peppers isn't as beautiful. Yes, you can just introduce a new
         | pepper and wrap the old hash into another hash using the new
         | pepper, but you'll still have to keep the older pepper around
         | to obtain the old hash during checks, creating risks if the
         | attacker gets access to the older pepper and an old db backup.
         | With AES usage, you can throw the old key away once all of your
         | db has migrated and you've updated your key backups.
         | 
         | Just make sure you use a suiting AES mode. If it turns out that
         | you xor'd all hashes with the same stream that depends on your
         | pepper only, it's not really helpful :).
        
         | hinkley wrote:
         | I can only think of two things, and they're manageable.
         | 
         | One, slightly longer password checks. And two, the temptation
         | to lean on the AES key and set the cost of the hash too low. In
         | the case the key does get out - we had an entire era where
         | people stole environment variables from servers - then you
         | decrypt the entire password file once and have cheaper guesses
         | per second.
        
         | kohtatsu wrote:
         | It's possible to change the pepper during login (same as
         | adjusting parameters).
         | 
         | The downside for the scheme is complexity and limited upside;
         | complexity gets a lot more attention when it comes to security
         | considerations.
         | 
         | Best practice especially needs to be simple; it's easy to mess
         | this stuff up and hard to understand. A lot of the comments on
         | this post betray a very poor understanding of password storage;
         | they simply haven't come across the correct information.
         | 
         | Overall pepper is good as long as you include salt. There are
         | times when the db gets leaked and the env variables don't.
         | 
         | There's nothing wrong with your scheme if it's implemented
         | properly, but being able to change the site-wide key is a
         | limited upside compared to using a pepper. There is an upside
         | though.
         | 
         | And all of this doesn't matter much as long as you do the bare
         | minimum of using a tuned pbkdf+salt and keep your stuff
         | patched.
        
         | dec0dedab0de wrote:
         | The only downside I think of is that it's not possible to
         | recover from an outage with just the code and a database
         | backup.
        
           | UnicycleSkewer wrote:
           | I guess that is true, but if you store the encryption key in
           | a secret store on Azure or AWS, I wouldn't really worry about
           | that.
           | 
           | Maybe the real question is why use a pepper over encryption?
           | 
           | They have the same downside (as you mentioned) but at least
           | you can change the encryption key without having all the
           | users change passwords. I don't see any advantage in using a
           | pepper over encryption, except maybe implementation
           | complexity.
        
             | hinkley wrote:
             | Pepper, encryption, they both guard against drive-bys,
             | which can happen for sure (missing backups anyone?) but
             | they're not the only thing that can happen.
             | 
             | Like any disaster preparedness situation, make sure your
             | strategy doesn't count on an asset you've already listed as
             | unavailable.
        
       | elchief wrote:
       | hashing is like a meat grinder
       | 
       | grind up a cow. store the ground beef somewhere
       | 
       | when a user wants to login, grind up the new cow in an identical
       | manner.
       | 
       | compare the new ground beef with the stored ground beef.
       | 
       | if match (the new cow is a clone of the old cow), authenticate
        
         | tobyhinloopen wrote:
         | Now I want a burger, but it's midnight. Thanks
        
       | alerighi wrote:
       | In fact hashing the password is better than encrypting them!
       | 
       | If you encrypt a password, it means that somewhere you have a key
       | that you use to decrypt it to check if it's valid on the user
       | login. It means that there is a way that you (or more importantly
       | an attacker) can use to decrypt the passwords.
       | 
       | Instead if you use a good hashing algorithm is practically
       | impossible to find the password given the hash. Yes if the
       | password is really simple you can get it, but come on, if the
       | password is really simple what's the point of protecting it?
       | 
       | By the way I think that we should phase out password anyway, I
       | mean that I prefer to implement in the applications that I
       | develop a password-less authentication: when you want to sign in
       | a mail (or an SMS) is sent to you, you click on a link with a
       | temporary token and you are authenticated.
       | 
       | No password to remember, not having to implement forgot password,
       | change password, recover your password, not having to store the
       | password, not having the user have to choose a password, and I
       | hate choosing password (in fact I ended up using a password
       | manager that generates random passwords for me, but it's not the
       | ideal solution, because then password have to be synced on all my
       | devices, not all websites/apps have forms made correctly to
       | support password manager, and the password manager extension
       | (Bitwarden) goes in conflict with the integrated Firefox password
       | manager so I end up having password saved in the password manager
       | and other in Firefox and it's a mess).
        
         | YetAnotherNick wrote:
         | You generally encrypt the hash of the password. Pepper can be
         | thought as a form of encryption.
        
         | leephillips wrote:
         | Every time I want to use the service I have to go through this?
         | I don't think I would like that. Much easier to just paste in
         | my password. Plus these emails are like sending passwords in
         | plain text. If they are intercepted someone can impersonate me.
        
           | runbyfruity wrote:
           | 1. If someone intercepts your password you're screwed anyway.
           | How many of your emails are intercepted regularly?
           | 
           | 2. If someone has access to your email, you're screwed anyway
           | because they can lock you out and reset every password.
           | 
           | Your email password, effectively, becomes the password for
           | that website. I.e. security-wise, I think they're equivalent.
        
         | matthewmacleod wrote:
         | _By the way I think that we should phase out password anyway, I
         | mean that I prefer to implement in the applications that I
         | develop a password-less authentication: when you want to sign
         | in a mail (or an SMS) is sent to you, you click on a link with
         | a temporary token and you are authenticated._
         | 
         | Please don't do this. For one thing, SMS is fundamentally
         | broken as a secure delivery method. But more than that... it's
         | just so, so deeply annoying.
        
       | agustif wrote:
       | What would you guys recommend for encrypting a base64 file stored
       | in database.
       | 
       | I've found about scrypt and LZ-String, but not sure what would be
       | best practice here.
        
         | TheDong wrote:
         | Neither scrypt nor lzma are encryption.
         | 
         | If you use scrypt, you won't be able to get the file back out
         | ever again.
         | 
         | If you use lzma, it's compressed, not encrypted, and anyone who
         | gets the compressed data can trivially decompress it.
         | 
         | Consider using an nacl secretbox if you need to encrypt it.
         | 
         | Consider very carefully where you'll store the password.
         | 
         | Does the user input it each time they access the file (in which
         | case use a key-derivation-function on their password)? Do you
         | encrypt it with an application key? Per-user key stored in
         | vault? Do you have a hardware encryption tool available (an
         | HSM) or something like aws KMS?
         | 
         | Your encryption is only as secure as you keep the encryption
         | keys.
         | 
         | See also [0] for some suggestions.
         | 
         | [0]: https://latacora.micro.blog/2018/04/03/cryptographic-
         | right-a...
        
           | agustif wrote:
           | Thanks for all the tips and the link, will research further
           | and see what better suits my needs.
           | 
           | For now I'm most worried about db being leaked so would look
           | into db encryption and prob I will go with application-key
        
         | cogman10 wrote:
         | What are you trying to accomplish?
         | 
         | I don't know why you are base64 encoding things before sending
         | them to the DB. Just use a binary blob.
         | 
         | scrypt is a hashing algorithm, not an encryption algorithm. So
         | that doesn't seem like what you want.
         | 
         | LZ-String is a compression algorithm, that's trivially
         | reversible.
         | 
         | The problem you'll run into is that the "right" encryption
         | algorithm is constantly changing. Probably the best thing to do
         | would be to not do it yourself, instead, rely on encryption
         | capabilities of your DB if provided. If you opt to doing your
         | own encryption, then be prepared to constantly maintain and
         | update it. Pushing that responsibility onto the DB makes that
         | burden a simple "make sure your DB is up to date" Which you
         | should be doing anyways.
        
         | iso8859-1 wrote:
         | did you read the article? there is no reason to encrypt
         | passwords.
         | 
         | scrypt is a popular KDF, i think you'll be fine with that.
        
           | agustif wrote:
           | Yes I did read the article, It's not a password, it's a PDF
           | file, it's contents I store them as plain base64 now, but I'd
           | rather have store them in a more secret fashion in case of a
           | leak...
           | 
           | If that makes sense...
        
             | StavrosK wrote:
             | libsodium?
        
             | iso8859-1 wrote:
             | for the encryption itself, you can use e.g. LibSodium or
             | AES (in a sensible mode!!!). of course, you'll need a key
             | too, which is where you can use a KDF. but without knowing
             | more about your threat model, it is hard to tell you how to
             | do the key derivation.
        
               | agustif wrote:
               | Hey thanks, well I'm a bit out of my area here but that
               | sounds helpful and will research it, thanks!!
        
               | StavrosK wrote:
               | Most of that is too low-level, libsodium/nacl is closer
               | to what they want.
        
       | pmontra wrote:
       | > The original password is never stored thus keeping it a secret
       | even from the website you provided it to
       | 
       | Never stored, hopefully, but the website has a chance of seeing
       | it everytime one signs in. A malevolent site or developer or
       | admin could store the password somewhere or try to reuse it on a
       | number of other well known sites. Hence, one different password
       | per site to protect also against the sites themselves.
        
         | mooreds wrote:
         | > Hence, one different password per site to protect also
         | against the sites themselves.
         | 
         | Preferably one generated by a password manager, large and
         | random and totally unrelated to any other password of the user.
        
         | hinkley wrote:
         | There was a class of password algorithm that used your password
         | and some other information as a seed for generating an
         | asymmetric cypher, but the original Stanford proposal was
         | apparently a bit light and nobody ever implemented it. I bumped
         | into some new algorithms in the same category, but I'm blanking
         | on the clever name they used to describe them all.
         | 
         | The server would only ever have your 'public key'. I'm not sure
         | where you get the saltiness to prevent lookup tables but still
         | let me log in from three devices with the same credentials.
        
         | kaoD wrote:
         | > the website has a chance of seeing it everytime one signs in
         | 
         | Indeed. I don't understand why challenge-response auth isn't
         | more widely deployed, or even part of the web APIs.
         | 
         | Sure, it doesn't mitigate ALL attacks, but it does mitigate
         | SOME attacks even if you're already on TLS.
        
       | bvinc wrote:
       | Someone should mention that one time that a leaked password
       | database from Adobe was actually encrypted, instead of hashed.
       | 
       | It lead to this XCKD comic:
       | 
       | https://xkcd.com/1286/
        
       | JeanMarcS wrote:
       | It's been a while since I'm doing both actually.
       | 
       | Since GDPR I tend to encrypt all not searchable data (address,
       | sometimes even names) in an encrypted JSON, including the
       | password hash.
       | 
       | Someone accessing my database will just have an integer ID, a
       | hashed login and an encrypted field.
       | 
       | Not sure if it's enough, but it seems ok to me.
        
       | notyourday wrote:
       | I have a fundamental question...
       | 
       | Why is the auth database a part of the application to begin with?
       | Why is it not externalized away behind a single service with a
       | bare minimum "set-password/is-this-my-password/trigger-x"
       | endpoints exposed to the application with per route/per
       | source/per question rate limiting? This is 2020, not 2001.
        
         | dudus wrote:
         | Because while service oriented architecture is currently "hot"
         | it's not a requirement for many systems and monolith is still
         | king in most corporate environments.
         | 
         | It's not just because the decade counter changed that everyone
         | must rewrite their systems using the latest fad.
        
           | notyourday wrote:
           | If you have a single database, located on a single server you
           | have a single security domain. No amount of hand waving is
           | going to create a magic security boundary that will not be
           | crossed by the most banal part of the application.
        
       | unlog wrote:
       | Question, is it good to hash passwords as = password + email (so
       | changing email requires input of password) + site wide long
       | random string (this string is same for every user), thoughts?
        
         | hansvm wrote:
         | You'll be better off with a per-user random salt than the
         | <email>+<site_const> scheme. If you later want to
         | include/exclude a re-auth flow to your email change process
         | then you retain that flexibility (though as an end-user I
         | dislike such additional barriers -- I suppose they thwart
         | cookie stuffing and other kinds of vulnerabilities if your
         | service is broken in that way, but I still don't like it).
        
         | social_quotient wrote:
         | Maybe still with a salt? Otherwise I'd think it would still be
         | reasonably hackable cause both things can (could) be known.
         | 
         | The only thing that bothers me here (not sure why) is something
         | about the fact that if the user changes their email you get a
         | pass change as well and that might signal an account take over
         | if your system is analyzing behavior stuff like that. Could be
         | wrong on my gut feeling here.
        
           | user5994461 wrote:
           | Hashing email + password is fine.
           | 
           | The email is the salt. It's different for every hash which is
           | all that's needed from a salt.
        
             | et-al wrote:
             | Unfortunately, email is not a unique salt in the context of
             | the internet. If the owner of the email uses the same
             | password elsewhere (very likely), it's probably already in
             | a rainbow table.
             | 
             | So just generate and store a random salt instead.
        
               | user5994461 wrote:
               | That is nonsense. You might want to check again what's a
               | rainbow table and how it's used, because it's not what
               | you think ^^
               | 
               | It's possible that another service use the same hashing
               | method and email as salt and password. It's irrelevant at
               | best when it comes to security. If the password was
               | cracked it would make it's way to dictionaries, the
               | password is compromised irrelevant of the salt and the
               | hashing method.
        
       | srtjstjsj wrote:
       | Troy doesn't understand users. I know how this stuff works and
       | the blog post had me snoozing. Users don't have room in their
       | brain for both "encrypted" and "hashed". All they care is if they
       | are secure, and if some pro tells them the vendor is lying.
       | 
       | Why should they be expected to know? They are receiving an email
       | from a professional IT specialist who couldn't even figure out
       | how this stuff works.
       | 
       | It's the vendor's job to get it right, and lawyers and
       | activists's role to hold them accountable.
        
       | dvt wrote:
       | I'm not sure why implementing pepper (alongside, or even instead
       | of, salt) is so rare. It's arguably much easier to implement than
       | salt, and protects against both attacks described here.
       | 
       | The only caveat is that your database isn't coupled tightly with
       | your application code, so your pepper remains secret even if your
       | DB is breached (which is usually the case).
        
         | mberning wrote:
         | I have wondered the same thing. Make it a piece of data that
         | comes in from the environment or a secrets manager. It's not
         | bulletproof, but if done correctly seems like it makes the
         | whole hashing scheme a little better.
        
           | lookingfj wrote:
           | If you are doing this isn't it pretty much the same as
           | encrypting it with a key?
        
             | liambuchanan wrote:
             | encryption is non-deterministic
        
               | quesera wrote:
               | Some encryption algorithms are (effectively) non-
               | deterministic, e.g.: DUKPT, RSA-OAEP
               | 
               | Most encryption algorithms are deterministic, and most
               | password authentication schemes depend on that fact.
        
               | srtjstjsj wrote:
               | Passwords aren't encrypted, so why would deterministic
               | encryption matter?
        
               | iso8859-1 wrote:
               | if that was true, this article wouldn't exist:
               | https://en.wikipedia.org/wiki/Deterministic_encryption
        
         | dec0dedab0de wrote:
         | pepper instead of salt is a bad idea because if your pepper is
         | leaked the attacker can brute force all of your passwords at
         | once.
         | 
         | The main argument I've heard against pepper is because people
         | are afraid of losing the pepper. It either needs to be directly
         | in your code which is easier to leak, or out of band which is
         | easier to lose.
         | 
         | edit: Does anyone else want to goto waffle house whenever they
         | talk about salting and peppering their hash? Too bad the
         | closest one is an hour away.
        
           | dvt wrote:
           | > pepper instead of salt is a bad idea because if your pepper
           | is leaked the attacker can brute force all of your passwords
           | at once.
           | 
           | This isn't true, you could simply do encrypted_pw =
           | md5(pepper + md5(password)) or whatever.
           | 
           | Edit: Getting a bunch of comments on this, just want to
           | clarify that I used md5 purely to illustrate a one-way
           | hashing function. In actual practice, you'd use something
           | else (HMAC with SHA256 most likely).
        
             | dec0dedab0de wrote:
             | If that gets leaked the attacker could brute force that,
             | and match the results to your entire list of hashes. If
             | they're salted, they would still have to brute force each
             | password individually.
        
               | dvt wrote:
               | Totally agree with this, hence the caveat that the code
               | doesn't get leaked/compromised :)
        
             | marcinzm wrote:
             | How does that help? They can iterate through possible
             | passwords and generate md5(pepper + md5(password)) just as
             | easily as md5(pepper+password). The point is that they can
             | iterate ONCE and match against all passwords in the DB.
             | With salt they have to iterate for each row in the DB which
             | is much more time consuming.
        
             | taywrobel wrote:
             | Please not md5. Please.
        
             | noodlesUK wrote:
             | I know this is just a comment on HN, but I want to point
             | out that MD5 is not a password hashing function, and is
             | broken even for a number of other hash purposes. For
             | passwords something like argon2id or another modern slow
             | hashing function is appropriate, and for general purpose,
             | SHA2 and SHA3, as well as BLAKE2 (and maybe BLAKE3) would
             | be good choices.
             | 
             | Further, there's so little reason not to salt, so you ought
             | to do it. It's built in to the hash strings in most modern
             | pw hashes. Peppers are also a great idea. Defence in depth!
        
               | sillysaurusx wrote:
               | MD5 is broken, but HMAC-MD5 is still impossible to break
               | afaik. And md5(pepper + md5(pw)) is basically HMAC.
               | 
               | Not commenting on the overall idea, just pointing out
               | that the criticism of md5 happens not to be valid in this
               | case. I was surprised too.
        
             | zemnmez wrote:
             | am I missing something here? the attacker still only needs
             | to know the pepper to brute force all the passwords with
             | this scheme. Since the pepper is deterministic, and
             | especially with md5 which is already extraordinarily quick
             | to reverse, the attacker can just take md5(pepper) then do
             | the extremely quick operation of the hash extension
             | md5(password)
        
             | pdevr wrote:
             | The only unknown in that equation, once you get hold of
             | pepper, is password. So, what added security does it
             | provide, other than requiring another md5 computation?
        
             | buzzerbetrayed wrote:
             | I think you don't quite understand the purpose of a salt.
             | Pepper and salt protect against very different things. And
             | frankly, salt is _much_ more important.
        
             | kohtatsu wrote:
             | SHA256 is also no good for storing passwords, you need to
             | use a PBKDF like scrypt, bcrypt, or pbkdf2.
             | 
             | The SHA-family cryptographic hash functions are
             | purposefully designed for throughput, if you combine them
             | thousands of times like in PBKDF2 they can be fine. One
             | round of SHA256 is trivial to brute-force especially with
             | the plethora of ASICs available.
             | 
             | HMAC is also completely unnecessary here, and see the
             | article title for your variable naming: it's not
             | encrypted_pw it's hashed_pw.
        
           | [deleted]
        
           | LocalPCGuy wrote:
           | If the pepper is stored as an environment variable, adding it
           | in addition to the salt can be a minor increase in the
           | password security. The thing is it often isn't that hard to
           | get if someone has access to your server.
           | 
           | If it's just the db that is exposed though, it could be a
           | small added layer of protection.
           | 
           | And yes, I would not ever do it instead of a salt.
        
             | agustif wrote:
             | Would in this scenario be running each service
             | (database/backend/frontend) in separated
             | clouds/envirorments be benefitial to mitigating risks?
             | 
             | Let me explain. for example, I might have my NextJS
             | frontend in Vercel using it's secret management /env tools.
             | 
             | The backend as a vanilla node-apollo-server-express could
             | probably be on a cheap VPS, being monitored/restarted/load-
             | balanced by PM2.
             | 
             | The database would be cloud, either PostgreSQL as a
             | Service, or Fauna or something.
             | 
             | Would this scenario be better than just cramming everything
             | into a VPS and trying to get that as secure/closed down as
             | possible and be done with it (do monthly updates and
             | whatnot)...
             | 
             | I've faced recently this conundrum at job. Small new app
             | will not have more than a few hundred concurrent users
             | optimistically...
        
         | skissane wrote:
         | > The only caveat is that your database isn't coupled tightly
         | with your application code, so your pepper remains secret even
         | if your DB is breached (which is usually the case).
         | 
         | There are many attack scenarios in which storing a secret
         | separate from the DB doesn't get you much at all. Suppose an
         | attacker finds an RCE vulnerability in the application - then
         | they can slurp up the contents of the DB, but they can read the
         | pepper from the configuration too.
         | 
         | Suppose they just have a SQL injection - they can't directly
         | get the pepper from a SQL injection, assuming it is being
         | stored somewhere outside the database. But, it may help them do
         | it indirectly - for example, they could UPDATE their account to
         | have admin privilege, and then access admin-only features of
         | the application which may end up revealing the pepper. I've
         | seen many apps which have admin-only screens to run arbitrary
         | scripts, view configuration files or environment variables,
         | install plugins, etc - those kind of features are helpful in
         | supporting the application, but can be used to turn a SQL
         | injection into more complete control over it
        
           | notyourday wrote:
           | > There are many attack scenarios in which storing a secret
           | separate from the DB doesn't get you much at all. Suppose an
           | attacker finds an RCE vulnerability in the application - then
           | they can slurp up the contents of the DB, but they can read
           | the pepper from the configuration too.
           | 
           | If the auth is a service accessing only via some remote
           | access protocol that only allows a minimum number of
           | operations that do not map directly into database commands
           | they cannot exploit RCE in the app to get auth database.
           | 
           | Such service can also enforce reasonable rate limits and
           | quotas, something that a regular direct database access can't
           | enforce.
        
             | benlivengood wrote:
             | It's really hard to store pepper in a system meaningfully
             | more secure than the password hashes themselves. For any
             | suggestion of a safer way to store pepper my response is
             | "store the password hashes there instead". Until you get to
             | the point of decrypting password hashes in a TPM I don't
             | see any benefit and at that point you've switched to a
             | hardware solution.
        
               | notyourday wrote:
               | That's not the argument though - the argument is that
               | storing high security rarely accessed information (
               | hashes of passwords / encrypted passwords ) that are
               | needed for a very limited number of well defined
               | operations on the same system within the same security
               | domain with the low security often accessed information
               | with a high number of not well defined operations is what
               | responsible for majority of hashed/encrypted credential
               | leaks anyway.
               | 
               | You are going to have a much harder time getting data
               | from a service that only speaks HTTPs with 6 endpoints
               | that can only be fed 1 type of JSON with only specific
               | fields present per end point rate limited to rates per
               | second that make sense for those individual end points
               | with a database backing it being internal to that service
               | which gets 15 deploys per year than from a Gigantic
               | Database Supporting Application That Does Everything For
               | Users and Business and Marketing and Analytics that keeps
               | changing based on weekly sprints.
        
           | agustif wrote:
           | Admin tools should probably be IP whitelisted instead than
           | open to the world if admins are few?
        
             | charwalker wrote:
             | Is that not the default? Err on the side of better
             | security?
        
         | hn_throwaway_99 wrote:
         | A pepper is essentially a secret encryption key (it's a long
         | secret string that's added to the password and the salt to
         | ensure more entropy). With cloud key management services (e.g.
         | both AWS and GCP have a KMS), I think it's more beneficial to
         | just _encrypt the hash_ before putting it in your database.
         | Process looks like this:
         | 
         | Upon password creation:
         | 
         | 1. Generate hash as hash of password + salt.
         | 
         | 2. Encrypt the hash with a public key from KMS (you can store
         | the public key in your server code).
         | 
         | 3. In your database store the encrypted hash, the salt, plus
         | some "key ID" that identifies which KMS public key you used
         | (this is so you can rotate keys later).
         | 
         | Upon user login to verify the password:
         | 
         | 1. Retrieve the user's encrypted password hash, salt and KMS
         | key ID from the database.
         | 
         | 2. Make a call to KMS to decrypt the hash (KMS internally
         | stores the corresponding private key but never lets you access
         | it).
         | 
         | 3. Then hash the password the user entered + salt and compare
         | it to the decrypted hash to see if there is a match.
         | 
         | Benefits of this are:
         | 
         | 1. If an attacker steals your database, they can't decrypt any
         | of the passwords or the password hashes.
         | 
         | 2. KMS _never_ exposes the private key of the async key pair,
         | so you know this won 't get exposed either. The only way to
         | decrypt something is to make an API call to KMS.
         | 
         | 3. Thus, the only valid attack really is if the attacker is
         | able to gain the same access privileges as your server. But
         | even then they _still_ need to call KMS one-at-a-time to
         | decrypt hashes, and all of those KMS calls are logged in an
         | audit trail, so it should be much easier to see if you have
         | anomalous calls to KMS. There is a huge benefit here in that it
         | is impossible to do bulk decryption without a giant audit
         | trail.
        
         | edflsafoiewq wrote:
         | > It's arguably much easier to implement than salt
         | 
         | Salting is easier since it can be completely wrapped up in the
         | key derivation function. The programmer doesn't have to know
         | anything about it, they just use generate_key(passwd) and
         | check_password(passwd, key).
        
         | zemnmez wrote:
         | you really shouldn't be implementing your password hashing
         | algorithm from basic crypto primitives. s/bcrypt works right
         | out of the box with no config.
        
       | isoskeles wrote:
       | > Saying that passwords are "encrypted" over and over again
       | doesn't make it so. They're bcrypt hashes so good job there, but
       | the fact they're suggesting everyone changes their password
       | illustrates that even good hashing has its risks.
       | 
       | This is correct, but I am going out on a limb and guessing that
       | legal counsel had something to do with the wording here (which is
       | perplexing because I tend to expect legal definitions of terms to
       | be more specific).
       | 
       | I was at an organization that also had a data breach, and legal
       | counsel advised us to write a similar email when disclosing
       | publicly that the breach occurred. I was personally on multiple
       | phone calls with legal counsel about this, and it was quite
       | frustrating to try and explain the difference between encryption
       | and hashing, or stay on point with the fact that our passwords
       | were _not_ encrypted, trying to get people to stop using that
       | word on phone calls. Early on, they 'd ask questions like, "But
       | aren't your passwords encrypted?!" And you'd have to explain, no,
       | they're not, they're hashed, which is most likely _better_ than
       | encrypted (although I 'm open to being proven wrong on that).
       | 
       | They were, also, mostly useless on explaining what their
       | perspective of encryption was. I never got an explanation from
       | counsel, and at best, I was linked to a blog post that suggested
       | some security _best practices_ (not a legal definition of
       | anything we were liable for).
       | 
       | The sad thing is, with a data breach like that, you probably do
       | (and should) feel terrible for your customers, anyone who trusted
       | you with their emails, passwords, etc. But the laws surrounding
       | it are confusing enough to make it easy for some people to push
       | this out of their mind and just focus on, "What is the best thing
       | we can do to legally cover our asses?" Even if that means saying
       | factually incorrect or misleading things like, "Your passwords
       | were encrypted."
        
       ___________________________________________________________________
       (page generated 2020-09-04 23:00 UTC)