It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I'm sure there's something fundamental to all of this that simplifies the whole concept that I'm missing, but here goes:
OK, you salt & hash passwords for security, but what about the code that does it?
If you're on a host or vps, can't "someone" get ahold of your source b/c you compiled it there? Or, if they can access your database, can't they access the program that does the encryption/decryption and bruteforce it until they get the algorithm?
I know nothing can ever be 100% secure, but how can security be improved in this context?
Salting will protect the data somewhat from a dictionary or rainbow table attack in the case that your data was compromised. Brute force is not impossible, but will be slow and will need to be performed again for each password hash. If salting was not done, brute force attacks become much easier to attain.
Contrary to what some say, the salt is not protected in any special way (nor does it need to be), but is present in plain text as appended to the hash. It does however, need to be unique for each hash or it becomes pointless for this use. This is in contrast to a pepper that is used for all hashes and must be protected. Because of this distinction, salting is generally preferred unless access to the pepper is guaranteed to be restricted (not an easy task).
If you want improved security, don't use a shared host. And don't allow direct access to the database. And don't allow anyone that hasn't been prescreened to access your system. In a practical sense, these aren't always viable options. So just use a salt and live with it :)
There's nothing "hidden" in your source code regarding the hash algorithm. In fact, you should be using a proven, well-known implementation of a strong hash and not implementing the algorithm yourself.
The salt is the part that needs to be protected. That salt is not part of your code (or should not be) but rather should be stored in some sort of file storage / data base (depending on your application), and should be applied on a per-user bases (user Joe should have a different salt for his password than user Fred).
To be sure, it is critically important to protect the salt used with each user's password. That's where proper file system / database permissions come into play.
On another note, your code should also be protected from any unauthorized user as well, but not for the reason of protecting the salt (at least not directly... if someone can access the salt, or just replace your code with their own, entirely bypassing the authentication check).
Related
I am security analyst and I had been asked this question Is SHA1(3DES-CBC) a good encryption for storing passwords in database?
However, to my knowledge I feel use of salt for storing any sensitive information. And I feel CBC mode is vulnerable on certain protocols. And I feel this is the best pratice https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet
Please correct my understanding of the above.
However, I am trying to understand the technical implication of SHA1(3DES-CBC) to better explain my team of its issues in implimentation. Please advise me on the same.
Fast hashing algorithms like SHA* are never a good choice to hash passwords, instead you should use a slow key-derivation function with a cost factor like BCrypt or PBKDF2.
I couldn't find much information about "3DES-CBC" in combination with SHA1, but both (SHA1 and DES) are hash functions without iterating.
However, to my knowledge I feel use of salt for storing any sensitive information ...
John Stevens of OWASP put together a good document on server password security and storage. It walks through the attacks and threats, and then adds steps to neutralize the threats. Here are the references to the OWASP material (you only referenced one of them):
Password Storage Cheat Sheet
Secure Password Storage Threat Model
And I feel CBC mode is vulnerable on certain protocols...
I don't believe this is correct. A block cipher operated in CBC mode is a pseudo random function. It posses the PRP-notion of security. However, it can't be used in a vacuum. Hence, the reason you need understand the material in the two OWASP references.
SHA1(3DES-CBC)...
I'm not sure what the purpose of the composite function is. You'll have to ask the developers what their security goals are, and what threat it neutralizes. Naively, I'm going to say AES/CBC or 3DES/CBC alone should have been sufficient.
You also have the key storage problem to contend with. Its known as the "Unattended Key Storage" problem, and its a problem without a solution. See Peter Gutmann's Engineering Security.
NO!
If you're storing passwords in a database, you should be using bcrypt or scrypt. bcrypt has been analyzed by numerous cryptographers over the years, and is the 'defacto' password hashing algorithm.
SHA1 is bad because:
It can be run quickly (bad, makes it vulnerable to brute force).
It is susceptible to collision attacks (this means attackers don't even need to brute force the password).
It can be easily reversed if you're not using a salt (rainbow tables).
bcrypt is great because:
It's very slow (slows down attackers trying to brute force).
It requires a lot of CPU (this means attackers need many computers, with large CPUs).
It has no collisions.
scrypt is just like bcrypt, but also requires a lot of memory to compute a hash, further slowing down attackers. scrypt is relatively new, however, so you might want to stick with bcrypt for now.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
Suppose I were designing a web service with modest security requirements. For the most part, the threat model would be more about bored college students and less about anything you'd ever find in a spy novel. Would there be anything practically wrong with using the following password storage scheme?
salt || hash(site || password || salt)
where site is a unique identifier of my site, password is the user password, and salt is a user-specific random salt, and the hash is a general purpose cryptographic hash function like SHA-1, and || indicates concatenation.
I'm aware of certain issues that come up with this scheme.
The hash is (designed to be) fast to evaluate, and one iteration would leave particular weak passwords guessable.
Concatenation alone might cause "puns" in the overall input to the hash.
Now, there are certain security professionals on the Internet who would have me believe that, if this is my idea of a good enough password hashing scheme, I could not possibly deserve employment and desperately need to return to school. They point out that there are well-known password hashing schemes with far better properties from a security perspective. They demand that I switch to something better.
But really, should I? I have a bit of a counter argument here.
This is probably not going to be the weakest link in my service. Someone truly determined to break in has plenty of other avenues, and I should prioritize my time to secure the weaker ones.
Cost-benefit is already against the attacker's favor if my site has little intrinsic value. How much of a practical concern is it that a large cluster/botnet could recover a weak password in a day/week? Surely it has more valuable things to be doing that day/week.
Compromised accounts are more likely to happen because of trojans, keyloggers, social engineering attacks, what have you. Technology isn't the limiting factor in this security.
The more complex my scheme is, the more difficult it might be to move/expand to another platform. If I used bcrypt (hypothetically), I'd potentially have to write a bcrypt wrapper and incorporate that.
I really like this scheme. It's really simple. The implementation is hard to get wrong. And I would argue, for all intents and purposes with regard to an average site, it should be fine. Asking me to put in a better hashing scheme almost sounds like asking me to install a bigger lock on a door that is already very vulnerable to chainsaws.
If I would be doing something wrong here, I would very appreciate that someone point it out, especially in terms of practical and real-world-applicable concerns.
Thanks.
See What is the point of salt and hashing if database is accessible?
Salts prevent (some) rainbow table attack sbut they they don't prevent dictionary or brute force attacks.
Use Scrypt or bcrypt instead, where Scrypt is much stronger but both uses a Proof of Work system to make it much harder to crack a password. See the OWASP Password Storage Cheat Sheet
From a pure hashing perspective, unless I'm reading your question wrong, you're proposing creating a hash of the password concatenated with a user specific random salt which is the usual approach. Any additional data involved in the concatenation won't make a whole lot of difference if you've already got a cryptographically random strong salt of sufficient length.
Then there's the old argument about which hashing algorithm is the most secure and of course bcrypt will trumps the likes of SHA - and particularly MD5 - due to it's adaptive native and ability to increase the hashing process duration to ward off brute force attacks.
However, you could pragmatically argue that for most general purpose website cases, SHA1 and above would be sufficient. When you look at the breaches we've seen in recent times, password disclosure is usually happening when they're either stored in plain text (obviously very vulnerable) or hashed without a salt (easily vulnerable to rainbow tables). Sure, the SHA derivatives will be faster to work through (particularly if it's a single hash), but in combination with a cryptographically random salt it's not a small task.
Case in point: the ASP.NET membership provider from Microsoft uses SHA1 and is very extensively used. There is no native bcrypt support (although third party libraries are available), which probably should tell you something about how Microsoft views the issue.
Finally, there's also the issue of password strength. Setting a long, strong requirement will obviously contribute to the strength of the hash against many brute force techniques. Of course there's the usability trade-off, but that's another issue.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Today I came up with a question about the web application conventions.
For the sake of security, if we store passwords of our users, most probably we are encrypting it (with MD5, SHA-1 etc.) and storing digested-hash in order to make them difficult or impossible to reverse.
Today there are many Rainbow Tables that are lookup tables of usual A-Za-z0-9 sequences up to 6 chars or widely used passwords. Let's say you are MD5-ing the user password once and storing the hash as password in database and someday hackers pwned your database and now they have many md5 hashes and e-mail addresses. Surely they'll look up passwords and when they got a preindexed match, they will try to login to that user's e-mail account.
Here this can be easily solved by digesting the message twice or simply reversing it. However I am wondering about what is the convention about this problem and how (as far as you know) enterprise applications or giants (Facebook, Google) solve this?
You use what is called a salt. Prepend some string that you make up before hashing. Prepend it also when you are checking the password. This is an application-wide string. This makes it much harder to look up via a rainbow table.
So if your salt is "kdi37s!!" save this in the db md5(kdi37s!!P#$$w3rd) and do the same when checking.
Use a little bit of salt and make a hash using sha1 or so.
Check out PBKDF2, it is one of the correct way to do it.
If you use an algorithm like BCrypt and salt (which uses the blowfish block cipher), it makes your db pretty safe against brute force attacks. Naturally, you want to require that your users have a reasonable amount of complexity in their password, if a user's password is a its not going to take long to guess it.
If an attacker gets a copy of your db, only being able to try 10 or so passwords a second will mean it will take a real long time to gain any passwords. If you are worried about Moore's law and would like to future proof this, you can specify a cost and make the algorithm even slower.
The trouble with a pure SHA/X or MD5 password hash is that by-design these algorithms are very fast, this makes it very sensitive to brute force attacks. Of course if you don't salt your hashes there are tons of rainbow tables that make cracking all the passwords in your db trivial.
Is there any benefit in salting passwords for a strong, unique (not used for other applications by the user) password?
Salting (as I am aware) protects against rainbow tables generated with a dictionary or common passwords. It also protects against an attacker noticing a user with the same hash in another application.
Seeing as a strong password will (likely) not appear on a generated rainbow table, and a smart user will use unique passwords for each application he wants to protect, does salting protect an already "smart" user?
this is theoretical. i have no inclination to stop salting.
in essence, doesn't the salt just become part of the password? it just happens to be supplied by the gatekeeper rather than the user.
If you can guarantee that all users will never reuse passwords, and that none of their passwords will ever be of a form that it is computationally feasible to precalculate colliding hashes for, then indeed the salt is little additional benefit.
However, the salt is also of little additional cost; while these premises are very hard indeed to guarantee, and the cost of being wrong about them is high. Keep the salt.
Apart from rainbow tables there are also bruteforce tools to resolve a hash. This doesn't prevent unsalted hashes from being resolved. It only takes a longer as stronger the password is. Salting would certainly still make sense.
This feels like you want to make an assumption, then base your security on that assumption. When you assumption becomes bad, for whatever reason, then your security becomes bad.
So how might your assumption (that strong passwords don't need salting) become invalid?
1) Over time, larger, more comprehensive rainbow tables are generated. This is something I would worry about if it is up to your user to choose a strong password. They might think they have done a good job, and you and your safety checking might think they have done a good job too, but later it turns out their thought process creating the password was easily duplicated by stringing a few words and numbers together.
2) If users cannot choose their password, your strong password generation process might, due to bug or whatever, turn out to be not as strong as you want.
3) Your user might be too lazy to come up with a site-unique/strong password! This is surely the most important problem. Do you really want to generate a system which is usable only by cryptographic experts? :)
Rainbow tables are most definitely not restricted to dictionary passwords or the like. Most tend to include every character combination up to some max length - after all, it's a one time cost for generation. Do your users all use 12+ character passwords? Unlikely.
I've read several stackoverflow posts about this topic, particularly this one:
Secure hash and salt for PHP passwords
but I still have a few questions, I need some clarification, please let me know if the following statements are true and explain your comments:
If someone has access to your database/data, then they would still have to figure out your hashing algorithm and your data would still be somewhat secure, depending on your algorithm? All they would have is the hash and the salt.
If someone has access to your database/data and your source code, then it seems like no matter what your do, your hashing algorithm can be reversed engineered, the only thing you would have on your side would be how complex and time consuming your algorithm is?
It seems like the weakest link is: how secure your own systems are and who has access to it?
Lasse V. Karlsen ... brings up a good point, if your data is compromised then game over ... my follow up question is: what types of attacks are these hashes trying to protect against? I've read about rainbow table and dictionary attacks (brute force), but how are these attacks administered?
The security of cryptographic algorithms is always in their secret input. Reasonable cryptanalysis is based on an assumption that any attacker knows what algorithm you use. Good cryptographic hashes are non-invertible and collision resistant. This means that there's still a lot of work to do going from a hash to the value that generated it, regardless of whether you know the algorithm applied.
If you used a secure hash, access to the hash, salt, and algorithm will still leave a lot of work for a would-be attacker.
Yes, a secure hash puts a very hard to invert algorithm on your side. Note that this inversion is not 'reverse-engineering'
The weak link is probably the processes and procedures that get those password hashes into the database. There are all sorts of ways to screw up and store sensitive data in the clear.
As I noted in a comment, there are attacks that these measures defend against. First, knowing the password may lead to authorization to do things beyond what the contents of the database suggest. Second, those passwords may be used elsewhere, and you expose your users to risk by revealing their passwords as a result of a break-in. Third, with hashing, an insider can't exploit read-only access to the database (subject to less auditing, etc.) to impersonate a user.
Dictionaries and rainbow tables are techniques for accelerating hash inversion.
You question is about using passwords as an authentication mechanism and how to securely store these passwords in a database using a hash. As you probably already know the goal is to be able to verify passwords without storing these passwords i clear text in the database. In this context let me try to answer each of your questions:
If someone has access to your database/data, then they would still have to figure out your hashing algorithm and your data would still be somewhat secure, depending on your algorithm? All they would have is the hash and the salt.
The basic idea of hashing passwords is that the attacker has knowledge of the hashing algorithm and has access to both the hash and the salt. By selecting a cryptographic strong hash function and a suitable salt value that is different for each password the computational effort required to guess the password is so high that the cost exceeds the possible gain the attacker can get from guessing the password. So to answer your question, hiding the hash function does not improve the security.
If someone has access to your database/data and your source code, then it seems like no matter what your do, your hashing algorithm can be reversed engineered, the only thing you would have on your side would be how complex and time consuming your algorithm is?
You should always use a well-known (and suitably strong) hashing algorithm, and reverse engineering this algorithm is not meaningful as there is nothing hidden in your code. If you didn't mean reverse engineer but actually reverse then, yes, the passwords are protected by the complexity of reversing the hash function (or guessing a password that matches a hash value). Good hash functions makes this very hard.
It seems like the weakest link is: how secure your own systems are and who has access to it?
In general this is true, but when it comes to securing passwords by storing them as hashes you should still assume that the attacker has full access to the hashes and design your system accordingly by choosing an appropriate hash function and using salts.
What types of attacks are these hashes trying to protect against? I've read about rainbow table and dictionary attacks (brute force), but how are these attacks administered?
The basic attack that password hashing protects against is when the attacker gets access to your database. The clear text password cannot be read from the database and the password is protected.
A more sophisticated attacker can generate a list of possible passwords and compute the hash using the same algorithm as you. He can then compare the computed hash to the stored hash and if he finds a match he has a valid password. This is a brute force attack and it is generally assumed that the attacker has "offline" access to your database. By requiring the users to use long and complex passwords the effort required to "brute force" a password is significantly increased.
When the attacker wants to attack not one password, but all the passwords in the database a large table of passwords and hash value pairs can be precomputed and further improved by using what is called hash chains. Rainbow tables is an application of this idea and can be used to brute force many passwords simultaneously without increasing the effort significantly. However, if a unique salt is used to compute the hash for each password a precomputed table becomes useless as it is different for each salt and cannot be reused.
To sum it up: Security by obscurity is not a good strategy for protecting sensitive information and modern cryptography allows you to secure information without having to resort to obscurity.
what types of attacks are these hashes trying to protect against?
That type when someone gets your password from poorly secured site, reverses it, and then tries to access your bank/PayPal/etc. account. It happens all the time, and many people are still using same (and often weak) passwords everywhere.
As a side note, from what I've read, key derivation functions (PBKDF2/scrypt/bcrypt) are considered better/more secure (#1, #2) than plain salted SHA-1/SHA-2 hashes by crypto people.
If you have just a hash, no salt, then once they know your data (and algorithm) they can get your password via a rainbow table lookup. If you have a hash and a salt, they can get your password by burning a lot of CPU cycles and building a rainbow table.
If your salt is the same for all your data, they only need to burn a lot of CPU cycles once to build the table and then they have all the passwords. If your salt is not always the same, they need to burn through the CPU cycles to make a unique rainbow table for each record.
If the salt is long enough, the CPU cycles they need become very cost-prohibitive.
If you know your data security is breached, of course, you need to reset all the passwords immediately anyway, because as far as you know the attacker is willing to spend that time.
If someone has access to your database/data, then they would still
have to figure out your hashing
algorithm and your data would still be
somewhat secure, depending on your
algorithm? All they would have is the
hash and the salt.
This might be all a really dedicated opponent would need. Much of this answer depends on how valuable the data is, which would tell you how motivated the opponent is. Credit card numbers are going to be extremely valuable, and criminal attackers seem to have plenty of time and accomplices to do their dirty work. Some bad guys have been known to farm out key decryption tasks to botnets!
If someone has access to your database/data and your source code,
then it seems like no matter what your
do, your hashing algorithm can be
reversed engineered, the only thing
you would have on your side would be
how complex and time consuming your
algorithm is?
If they have access to your source and all the data, the question is going to be "how did you load your key into the memory of the server in the first place?" If it's embedded in the data or in the program code, it's game over and you've lost. If it was hand-keyed by an operator at the machine's boot time, it should be as secure as your trust in your operator. If it is stored in an HSM*, it should still be secure.
And if they have root-level authority access to your running machine, then they can probably trigger and recover a memory dump that will reveal the secret key.
It seems like the weakest link is: how
secure your own systems are and who
has access to it?
This is true. But there are alternatives that help improve security.
For bank-like protection, the kind that passes security and industry audits, it's recommended that you use a *Hardware Security Module (HSM) to perform key storage and encryption/decryption functions. The commercial strength HSMs we're looking at cost 10s of thousands of dollars or more each, depending on capacity. But I have seen hardware encryption cards that plug into a PCI slot that cost substantially less.
The idea behind an HSM is that the encryption happens on a secure, hardened platform that nobody has access to without the secret keys. Most of them have cabinets with intrusion detection switches, trip wires, epoxied chips, and memory that will self-destruct if tampered with. Not even the legitimate owner or the factory should be able to recover the database key from an HSM without the set of authorized crypto keys (usually carried on smart cards.)
For a very small installation, an HSM can be as simple as a smart card. Smart cards aren't high performance encryption devices, though, so you can't pump more than about one decryption transaction per second through them. Systems using smart cards usually just store the root key, then decrypt the working database key on the smart card and send it back to the database accessing system. These will still yield the working database key if the attacker can access running memory, or if the attacker can sniff the USB traffic to and from the smart card.
And I have no experience getting TPM chips to work (yet), but theoretically they can be used to securely store keys on a machine. Again, it is still no defense against an attacker taking a memory dump while the key is loaded in memory, but they would prevent a stolen hard drive containing code and data from revealing its secrets.
A hash cannot be reversed. Conceptually, think of a hash as taking the value to be hashed as the seed to a random number generator, then taking the 500th number that it generates. This is a repeatable process, but it is not a reversible process.
If you store a hashed password in your database, when your user logs in, you take his password from the input to the login page, you apply the same hash to it, and then you compare the result of that operation to what you have stored in the database. If they match, the user typed the right password. (Or, in theory, they could have typed something that happens to hash to the same value, but in practice, you can completely ignore this.)
The purpose of the salt is so that even if users have the same password, you can't tell, and also lots of other things which are equivalent to this idea. If the user's password is "secret", and the salt is "abc", then instead of making a hash of "secret", you hash "secretabc" and store the results of that in your database. You also store the salt, but this is perfectly safe to store -- you can't figure out any information about the password from it.
The only reason to safeguard the hashed passwords and salt is that if an attacker has a copy of it, he can test passwords offline on his own machine, rather than repeatedly trying to log in to your server, which you would probably lock him out after three attempts or something like that. Even if you don't lock him out, it's much faster to test locally than to wait for the network round-trip.
( OP )
brings up a good point, if your data
is compromised then game over ... my
follow up question is: what types of
attacks are these hashes trying to
protect against? I've read about
rainbow table and dictionary attacks
(brute force), but how are these
attacks administered
( discussion )
It's not a game, except to the attacker. Research these terms:
Sarbanes-Oxley
Gramm-Leach-Bliley Act (GLBA)
HIPAA
Digital Millenium Copyright Act (DMCA)
PATRIOT Act
Then tell us ( as thought provocation for you ) how do we protect against whom? For one thing, it is the efforts of innocents vis-a-vis intruders - and for another it is data-recovery if part of the system fails.
It is an interesting experiment that the original intent of tcp/ip and so on is advertised as being a weapon of war, survivability under attacks. Okay, so passwords are hashed - no one can recover them ...
Which, duh, includes the owner-operator of the system.
So you build a robust record locking tool that implements key controls, then political pressures force the use of brand-x tools.
You can read Federal Information Security Management Act (FISMA) and by the time you have read it some governmental entity somewhere will have had an entire disk either stolen or compromised.
How would you protect that disk if it was your personal identity information on that disk.
I can tell you from the caliber of Martin Liversage and jadeters they will be paying attention.
Here are my thoughts to your points:
If people have access to your database you have bigger security concerns than your hash algorithm and salt phrase. Hashes are somewhat secure, however there are problems such as hash collisions and hash lookups.
Hashes are one-way, so unless they can guess the input there is no way to reverse out the original text even with the algorithm and salt; hence the name one-way hash.
Security is about obscurity and layers of defense. If you layer your defenses and make determining what those defenses are you stand a much better chance of staving off an attack than if you relied on a single approach to security such as password hashing and running OS/network hardware updates. Throw in some curveballs like obsfucation of the web server platform and clear boundaries between the prod web and database environments. Layers and hiding implementation details buy you valuable time.
When hashing a password, it is one way. So it is very difficult to get the password even if you have the salt, source and alot of cpu cyles to burn.