[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)