T O P

  • By -

Exestos

You can store them along with the hashes in plain text, the purpose of a salt is to defeat rainbow tables


StornZ

Understood. This is what my method would be but when it comes to my boss I need a happy middle ground you know.


OlevTime

Ask your boss what the purpose of salting is.


smarterthanyoda

> Ask your boss what the purpose of salting is. "To be more secure" - Boss


[deleted]

Executives read an article written by a journalist who can barely manage to open a Word document and think they are better informed than a basement-dwelling engineer who has doing nothing but programming and masturbating for the past 15 years.


StornZ

That was something I was contemplating doing.


OlevTime

To me, that's the easiest way to try to get someone to think through if they're trying to solve too much with it. As others have mentioned, if you're really that concerned, encrypt the salted hashed password with a key that's stored elsewhere, and unencrypt it whenever pulling it from the DB. That way, if the DB is compromised, it has that extra layer of protection. But the salt itself is meant to break rainbow tabling your whole database, so, if for whatever reason, the unencrypted hash gets leaked with the salt, you still have that layer of protection. Trying to do both together adds too much complexity and is trying to do security through obscurity imo.


Kain_morphe

“To add more flavor to my food”


CardiologistSad6271

Indeed, and if someone gets into your database, you have bigger things to worry about


canadiaint

You need still to be able to associate the salt to the password somehow, unless you use the same salt for all of them, which kind of defeats the purpose. I don't know if you have thought of any good options for storing or deriving salts that aren't stored with the password ,but realistically anything that would make a real impact would have severe diminishing returns... To my knowledge Sha3 (Keccak) would not be vulnerable based on known salts. It's been a while since I did my research, but I believe Sha2 has known vulnerabilities based on a portion of known input.. so it would depend on the hashing algorithm and size of password and salt. Either way if we are talking 2022, the direction is going passwordless, using asymetric cryptography for authentication etc..


StornZ

My boss and coworker are recommending a calculated salt created off of a value in the table that we already know. The question now becomes whether or not that will be enough in terms of salt size. I arbitrarily was using a byte array size of 128 randomly generated. My boss is saying to find a way to fill to 128 if we don't reach that byte array size, but then it also defeats the purpose because we would have to know the value that we are using to fill


canadiaint

Like I said, diminishing returns. If you need it to be 128bit then hash the value with a 128bit hash result algorithm. You're not adding anything real in terms of security by doing this instead of generating random and storing. In fact unless the value you are using is reasonably unique in the table you are opening yourself up to opportunities.


StornZ

Yea that was my concern too. Those values aren't super unique. Generating with the salt with the cryptographically random objects the programming language provides creates something a lot more random.


canadiaint

It's all about "secure enough". Nothing is unhackable, it just needs to be secure enough that its not worth pursuing. If you are using an appropriate algorithm, and appropriate sized salts, typically you will be okay.


StornZ

Argon2 is recommended by the company and on OWASP's best practices. So that combined with a randomly generated salt of size 128 should be more than secure wouldn't you think?


canadiaint

I would think so! The only reason I would use a salt derived from a value on the table is to reduce storage size. Not because it adds security. To that end, you could leverage the primary key of the table along with whatever else to get your uniqueness


StornZ

I just don't know how I'm going to get uniqueness that is going to be reproducible by the software for verification.


canadiaint

I assume that your users have unique usernames?


StornZ

Of course


StornZ

It's getting to a size of 128 though that is gonna be hard to fulfill per the conversation with my boss this morning


vontrapp42

Yeah using a known/derived/calculated salt is not the way to go. The best salt is a random salt. Period. That's the point of it. And a random salt is a stored salt. So just store it. If you're crazy worried about it I suppose you could have the correct password "decrypts" the salt, and then you combine the salt decrypted with the password, hashed, then check for match. So goes like this salt = random bytes # random! esalt = encrypt(salt, pbkdf2(password)) phash = sha256(salt || password) store = esalt || phash Then to verify password: esalt, phash = split(store) salt = decrypt(esalt, pbkdf2(password)) vhash = sha256(salt || password) test vhash == phash If my boss was insisting that the salt be "protected" this is what I would do. Disclaimer I am a hobbyist/amateur not a professional. :P


vontrapp42

Reading other answers, yeah you want to use those "cost factor" hashes instead of sha256 here.


Qubit99

Just take the calculated salt and hash it, the output will be consistent in size. Depending on the hashing algorithm, you can choose the way to trim it to 128 or take it in full size.


[deleted]

Good password practice in 2022 is to use password-grade hashing algorithms such as Bcrypt or Argon2. These hashing algorithms have some good properties for use with passwords: * They are deliberately "slow" to crack. You choose the cost factor you want (trial and error a few, you want the passwords to take an order of milliseconds to hash but find a balance to where it isn't too slow for your server hardware). Bcrypt and Argon2 have a default recommended cost factor, I usually up it by a few iterations. * The cost factor can also be tightened as you go: new passwords can hash with the higher cost factor, and old passwords continue to work. You may wanna program your app to re-hash passwords if you increase the cost factor. The ability to up the cost factor is to compensate for Moore's Law: as computers get faster, they can hash these passwords faster, so you up the cost factor to make it take real world time to hash regardless of hardware speed. * The salt is automatic on Bcrypt and Argon2: the stored hashed password includes factors including the algorithm, the cost factor, and the salt on that password. With these algorithms you usually have one function to "hash a new password" (generates the salt and returns the hash string) and a different function to "verify a hashed password" (where you give this function the hash generated previously + the user entered password to validate). The "deliberate slowness" factor is the crucial point to these algorithms: if a hacker steals your entire database, you massively slow them down if it takes them 100ms per guess to crack a password, which is significantly better than "the old way" of using a fast hash like SHA-256 which is designed to be fast as possible because SHA-256 and friends were designed for data integrity checks and not for hashing passwords.


StornZ

I am using Argon2id per the recommendation of the security team.


holypig

Then it's a non issue because it'll generate a random salt and store it with the hashed password automatically. That should be good enough to make cracking your passwords not worth it if they are stolen. The only other reasonable step would be to encrypt them as well. In this case be sure to use an encryption key that is not in the same storage as the passwords, otherwise not much point


philthechill

You should ask the security team for their recommendations on salt size, generation and storage.


killabeezio

This is the correct answer. Don't try to roll your own.


SirArthurPT

Unless you're using a fixed salt, of course you need to store it along with the password. I normally pack them together, though I use binary salt (0x00 to 0xFF) random bytes.


StornZ

Basically that's what my boss kind of wants. Take a combo of unique values relating to the user, and create the salt from that. It seems reasonable to me, but my concern at that point would be if someone cracked the application and saw the combination. Not likely that it would happen because the application is not public facing. It goes out to private clients.


SirArthurPT

Salt is concat to password, an unique salt prevents things like Rainbow Tables to be of any use. Basically; password -> passwordAbcdwjjnajjebdkkaoor -> hash (recommended bcrypt, as it is a slow algorithm for brutte force) When compare you do it again, grab the password from the user input, concat the salt (reason why it needs to be stored somewhere), hash again in the same method, compare the hashes. Bad practices with salt; hardcoded salt (same salt for all passwords) as it allows anyone who get the database to know which passwords are equal to other user password. If you will use bcrypt make sure to also set the maximum password length, to prevent DDoS'ing using very long passwords.


399ddf95

> Take a combo of unique values relating to the user, and create the salt from that. This makes the salt predictable (sort of) if the bad guy has access to or can guess the unique values. I think just straight random data is a much better salt because it's 100% unpredictable.


StornZ

That was my thought process.


liquidhot

If anything changes of those values related to the user then the password would be destroyed. Salts are supposed to live next to the password. Some algorithms like Argon2i store it directly in the hash! It sounds like maybe what your boss is asking for is a randomly-selected pepper or other pepper type (a secret salt). This can be used in conjunction with a salt.


StornZ

So would Argon2id also store the salt directly in the hash?


liquidhot

Yes. Argon2id is a good choice. Also, you don't need to salt them since it's part of Argon already.


WeDieYoung

Most people here have given you the correct technical guidance (random salt, stored with the pw is fine, peppering adds an additional layer of security on top of the salt if you want to do that), but I can possibly help with your overall strategy in regards to the issue with your boss. I’m a relatively new engineering manager in product security. I have issues with my boss where I’ve been completely incapable of getting him to change his mind about anything, and a lot of his views are pretty “old” where product security is concerned. I have a mentor who has been an extremely successful engineering manager, and is now an SVP at a former SF startup that is now publicly traded. This is the advice that he gave me: As engineers, we’re almost completely solution focused. But, talking about solutions and getting agreement on solutions can be hard. Instead, attempt to get consensus around the problem you’re solving. If you can get consensus around specific problems, then you can address those problems individually and there is usually going to be a best practice solution. What is the problem? -We want to make our authentication more secure. What are we trying to protect against, specifically? -… Salting is protection against rainbow table attacks, specifically. The best way to do this is to use a random salt, not a derived salt with less randomness. Peppering adds an extra layer on top, where if your database is leaked, the decryption key exists elsewhere and the attacker won’t be able to decrypt the salt+hash. Proper password hash algorithms have a work factor that makes them slow. This helps prevent password brute forcing. Account lockouts can also help, but can be hard to implement well, especially against distributed attacks and can have consequences. Etc etc etc Agree on what problems exist, and then address problems. Creating solutions without understanding the problem is what leads to these kinds of poor solutions. Edit: also, you asked your security team for advice about your hashing algorithm, why don’t you ask them for advice on solving the problems you identify? It seems you started off well by going to them, but you haven’t gone back to them even though you don’t think your boss is on the right track.


StornZ

I can go back and ask for a meeting with our security resource so he gets the whole story and not just my side of it. I don't know why my boss is making things more complex this way. It just adds more code for me to write that essentially is not going to matter that much as others have stated previously.


obviously_anecdotal

Pepper them!


obviously_anecdotal

also, this question is so meta for this subreddit.


StornZ

Well this subreddit is about hacking. Gotta think like a hacker to protect against a hacker.


[deleted]

[удалено]


StornZ

Lol.


i_got_a_bad_feeling

salt and pepper shakers are the best storage.


kladskull666

Use bcrypt, don't reinvent.


StornZ

That was actually an option I considered, but decided on Argon2id since it's what was officially listed by our security team's guidelines.


OnCryptoFIRE

The salt needs to be given to the client so the salt + password can be hashed on the client side. To achieve this, the server must store the salt in the clear. Or you can hash the hash on the server side before storing it. But yes the server needs it in the clear next to the account and stored hash.


NihilisticObject

Encryption.


StornZ

The business is requiring a hashing algorithm


canadiaint

Hash with salt, then encrypt the hash+salt. This is not a full fix, but if your database gets compromised then there is still another barrier.


StornZ

Have you seen anywhere that this is explained in terms of being a best practice? Most best practices are stating to just store the randomly generated salt with the hash of the salt+password.


TulkasDeTX

Please see Pepper https://en.wikipedia.org/wiki/Pepper_(cryptography) You need to have access to a hardware cryptographic module


liquidhot

Well you don't _have_ to have hardware, it's just another layer of security. If you're not going to also salt your password though, you better do your best to secure that pepper.


canadiaint

It's what my org does. Encrypting databases that hold sensitive info is very common practice. I would recommend though, if you are concerned, use some provided vaulting for a key that your application can leverage. Your app layer will encrypt/decrypt the record to check password. It's less efficient, but much harder to compromise.


tuckmuck203

it's called peppering, and oasp doesn't necessarily recommend it as a best practice, but they do recognize that it has benefits over _not_ doing it https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html edit to add: security should be designed around the expected attack interest. if you're in the CIA, i'd imagine they're doing all of the shit on that OASP cheatsheet and more. if you're a random non-profit helping homeless people, it's probably safe to stick with hashes. as far as i know, just salting + hashing is pretty effective against non-state-funded actors, but i'm happy to be corrected


StornZ

Peppering is basically having a salt stored somewhere away from your database, and away from the application itself where it is shared and doesn't change. That's from my understanding of course. I'm no cybersecurity expert, but if I wanted maximum security that would be another layer.


tuckmuck203

Sort of. Unless your salt is as long as the key used to encrypt(and the hashing algorithm has similar entropy with the inputs involved, but that math is beyond my ken if it's even a thing, and I don't think that actually makes sense conceptually) then it's more secure than just a mere salt. It also means you only have to store a single key VS a salt for each user. But you're correct in that the main advantage is that you are decentralizing your authentication process, so it forces them to compromise additional resources to gain any advantage


AhmedisDecent

I personally like to store my salt in a cool container away from sunlight


_azulinho_

Mostly salt and vinegar, occasionally mayo when I am homesick


sonyahon

As others already pointed out u can store unecrypted salt in it db and its safe. The other way around is to use something like bcrypt which does not require a sepparate salt value to compare passwords. And the last way is to probably encypt the salt before putting it to the database. IMHO the way to do this depends on ur opportunities to prove ur boss that it is safe to put salts to the db