Edit: changed "iheartjustinbieber" to hash("iheartjustinbieber") in the last sentence.
Edit: changed "iheartjustinbieber" to hash("iheartjustinbieber") in the last sentence.
What kind of use did you have in mind with "trivially breakable"? hash(salt+pass) ?
My point is just that _some_ (not all) things considered unsafe in crypto is still good enough for this kind of use.
"The design of the HMAC specification was motivated by the existence of attacks on more trivial mechanisms for combining a key with a hash function. For example, one might assume the same security that HMAC provides could be achieved with MAC = H(key ∥ message). However, this method suffers from a serious flaw: with most hash functions, it is easy to append data to the message without knowing the key and obtain another valid MAC. The alternative, appending the key using MAC = H(message ∥ key), suffers from the problem that an attacker who can find a collision in the (unkeyed) hash function has a collision in the MAC. Using MAC = H(key ∥ message ∥ key) is better, however various security papers have suggested vulnerabilities with this approach, even when two different keys are used.[1][3][4]
No known extensions attacks have been found against the current HMAC specification which is defined as H(key1 ∥ H(key2 ∥ message)) because the outer application of the hash function masks the intermediate result of the internal hash. The values of ipad and opad are not critical to the security of the algorithm, but were defined in such a way to have a large Hamming distance from each other and so the inner and outer keys will have fewer bits in common."
The why crypto works is that cryptographers -- some of the most OCD pedants you will ever know -- find a nano-scale fracture in one small relatively unimportant part of an algorithm, and then wrench it open into a gaping lava-spewing chasm of exploitation and credit card theft.
Please just use best practices, but realize that they will be periodically be updated.
Cryptography comes down to much more than using the right primitives. You also have to use the right implementations of those primitives (timing attacks), combined in the right ways (double stream cipher failure), and you have to be sure that the properties you want give you the protection you want (CBC without mac doesn't give you authentication). If you aren't using something with a wikipedia page that describes the entire system, and has some papers describing it and suggesting attacks on it, then you are inventing your own cryptography.
With the new GPU password bruteforcing techniques, it is easier and faster to just rent more Amazon EC2 machines. They're that fast.
Yes it's more expensive than rainbow tables (which are practically free), but not prohibitively so. Especially not for a criminal org bent on cc fraud, anyway.
It's still better to be using a slower hash function, but a good salt helps.
1) slow hash function. 2) per user random salt. 3) everything you want
don't help if the password is "apple".
So also you need:
4a) force users to passwords with required length / non alphanumerical chars, ...
or
4b) relax the security requirements.
However, if you use the SAME salt for all your passwords, if I compromise your database I simply have to generate my own rainbow table of sha1(salt + actual_password) to use.
If you use a different salt for each user, I have to calculate one rainbow table per user, which is much more time consuming. That said, one user (an admin) is often enough to cause enough damage.
In general the math is trivial:
(alphabet_size ^ password_size) / hashes_per_second
gives you the amount of seconds needed to crack a password.
You can set hashes_per_second to 1 billion for attacks that a private can do with little money. Maybe set it to 1000 billions per second if you want to protect yourself against bigger entities. But once you enlarge the alphabet_size and the password_size it is fast to reach a point where no brute force attack is feasible at all.