For my Web class project I was told to make a website with login/logout functionality and one of the things my professors demanded was using hashing algorithms to encrypt the users password.
Is it smart to do 1 or more different algorithms to convert my data(in this case a string) before doing the hashing algorithm(ex: MD5, SHA-1,etc)?
No it's not.
Short answer, it won't increase security, and will probably only increase the risk of collisions.
Make sure you use an algorithm designed to hash password like PBKDF2 or BCrypt. Hashing algorithm like MD5 and SHA-1 were created to be efficient, not secure and therefore should never be used to hash password.
Also, use a salt to hash to password to prevent preimage attacks.
Related
I have a constant SALT that is appended to every cookie before it is encrypted with sha512. If I know the clear text and the final encrypted values of more than one cookie, is it possible to use a tool like john the ripper to guess the salt value?
The answers I found on the internet talk about finding the password, but i'm interested in finding the salt.
Short Answer:
No you can't.
Reasons:
First of all sha512 is a hashfunction. You can't "decrypt" hashfunctions. If it would be able to do this, sha512 would not be safe.
Days ago google found the first collision in 6,610 CPU-Years.
Source: First sha512 Hashcollsion
(This is not an attack!) They used an amount of distributed systems. So a normal program like john-the-ripper wouldn't be able to do this.
SHA512 is not encryption.
It would require a brute force attack across the salt range, if the salt is just a few characters or bytes the attack would easily succeed.
Depending on the usage an HMAC may be a better choice than just appending a salt, there are attacks (depending usage) on a concatenated salt.
If you use the same salt it will can discovered by the attacker who gains access to the system. A better method is to use a random salt with an HMAC and prepend the salt to the hash value, then it does not need to be secret. This assumes you need to be able to recompute the same hash from the same data
For passwords, where more security is needed, using a hash function with a salt does little to improve the security. Instead iIterate over an HMAC with a random salt for about a 100ms duration and save the salt with the hash. Use functions such as PBKDF2, Rfc2898DeriveBytes, password_hash, Bcrypt and similar functions. The point is to make the attacker spend a lot of time finding passwords by brute force.
I am reading this article and it seems like BCrypt is:
slow to compute a hash from a password (a good thing)
doesn't store a salt in the database but just in the password directly
uses a log_rounds parameter which says how many times to compute the internal hash function.
So the hash would look something like this:
hashed = hashpw(plaintext_password, gensalt(log_rounds=13))
print hashed
'$2a$13$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm'
But if that's what's stored in the database, if the database gets hacked, aren't we still vulnerable? The BCrypt hash contains the salt and the encoded password and so why is this better than just storing the salt and the password in the database (The article calls it bad solution #4)?
Is the major difference the slowness of BCrypt's hashing mechanism which makes it hard and expensive to BCrypt a long list of common passwords?
You can't just hash a password, if you do that it will be vulnerable to dictionary attacks; therefore you salt the password before hashing it; this is what BCrypt does.
Password salts can be public, however they must be unique for each password. The point of them is to prevent dictionary attacks on hashes (so you can't look through a list of premade hashes which corresponds to passwords).
Like PBKDF2, Bcrypt is an adaptive function; you can increase iterations later on to make the hash less vulnerable to brute force attacks as more computing power comes out. Despite this Bcrypt is harder to accelerate on GPUs than PBKDF2.
I want that when the original data or the password changes (I mean, any one of them changes, or both of them change), the encrypted data will always change. In other words, once the encrypted data is certain, then both the original data and the password will be certain, although they are not known to those who don't have the password.
Is there any good symmetric encryption algorithm that fits my specific need?
I assume that you use the password to derive the key for the cipher.
Changing key
Every modern encryption algorithm produces different ciphertexts when a different key is used. That's just how encryption usually works. If it doesn't have this property then everything is broken. All the usual suspect like AES, Blowfish, 3DES have this property.
Changing plaintext
The other property is a little harder to do. This runs under the umbrella of semantic security.
Take for example any modern symmetric cipher in ECB mode. If only a single block of plaintext changes then only the same block changes in the ciphertext. So if you encrypt many similar plaintexts, an attacker who observes the ciphertexts can infer relationships between those. ECB mode is really bad.
Ok, now take a cipher in CBC mode. If you use the same IV over and over again, then an attacker may infer similar relationships as in ECB mode. If the 10th block of plaintext changes, then the previous 9 blocks will be the same in both ciphertexts. So, if you use a new random IV for every encryption, then there is nothing an attacker can deduce besides the length without breaking the underlying cipher.
In other words, once the encrypted data is certain, then both the original data and the password will be certain
The previous paragraph may not be completely what you wanted, because now if you encrypt the same plaintext with the same key twice, you get different results (this is a weak security property) due to a random IV. Since you derive the key from a password, you may also derive the IV from the same password. If you use for example PBKDF2, you can set the number of output bits to be the size of key+IV. You will need to use a static salt value.
If you don't need that last property, then I suggest you use an authenticated mode like GCM or EAX. When you transmit ciphertext or give the attacker an encryption oracle then there are possible attack vectors when no integrity checks are used. An authenticated mode solves this for you without the need to use an encrypt-then-MAC scheme.
If all you care about is detecting when either the data or the password changes, create a file with the data and then append the password. Then use a cryptographic hash like SHA-2 on the file. If either the data or password changes, the hash will change.
Encryption algorithms are generally used to keep data private or to verify identities. Hashes are for detecting when two data objects are different.
The usual reason for encrypting data is that it will be placed in an insecure environment. If the user's encrypted data is in an insecure environment, an opponent can copy it and use software the opponent obtained or wrote, instead of your software, to try to decrypt it. This is similar to some of the controls put on PDFs in Adobe software, such as not being able to cut and paste from the document. Other brands of software may not enforce the no-cut-and-paste restriction.
If the opponent discerns the encryption algorithm, but uses the wrong password, the chances of getting the correct plain text are very small; for the popular modern algorithms, the chance is small enough to neglect compared to other everyday risks we must endure, such as life on earth being destroyed by a comet.
Digital signature, if I understood right, means sending the message in clear along with a hash of the message which is encrypted using a private key.
The recipient of the message calculates the hash, decrypts the received hash using the public key, then compares the two hashes for a match.
How safe is this? I mean, you can obtain the hash of the message easily and you also have the encrypted hash. How easy is it to find the private key used to create the Encrypted_hash?
Example:
Message Hash Encrypted_hash
-----------------------------------------
Hello world! 1234 abcd
Hi there 5678 xyzt
Bla bla 0987 gsdj
...
Given the Hash and the Encrypted_hash values, and enough of these messages, how easy/hard is it to find out the private key?
Because of the algorithms used to generate the keys (RSA is the typical one), the answer is essentially "impossible in any reasonable amount of time" assuming that the key is of a sufficient bit length. As long as the private key is not stolen or given away, you won't be able to decrypt it with just a public key and a message that was hashed with the private key.
As linked to in #Henk Holterman's answer, the RSA algorithm is built on the fact that the computations needed to decrypt the private key - prime factorization being one of them - are hard problems, which cannot be solved in any reasonable amount time (that we currently know of). In other words, the underlying problem (prime factorization) is an NP problem, meaning that it cannot be solved in polynomial time (cracking the private key) but it can be verified in polynomial time (decrypting using the public key).
Ciphers developed before electronic computers were often vulnerable to "known plain-text" attack, which is essentially what is described here: if an attacker had the cipher-text and the corresponding plain-text, he could discover the key. World War II-era codes were sometimes broken by guessing at plain-text words that had been encrypted, like the locations of battles, ranks, salutations, or weather conditions.
However, the RSA algorithm used most often for digital signatures is invulnerable even to a "chosen plain-text attack" when proper padding is used (like OAEP). Chosen plain-text means that the attacker can choose a message, and trick the victim into encrypting it; it's usually even more dangerous than a known plain-text attack.
Anyway, a digital signature is safe by any standard. Any compromise would be due to an implementation flaw, not a weakness in the algorithm.
A digital signature says nothing about how the actual message is transferred. Could be clear text or encrypted.
And current asymmetric algorithms (public+private key) are very secure, how secure depends on the key-size.
An attacker does have enough information to crack it. But it is part of the 'proof' of asymmetric encryption that that takes an impractical amount of CPU time: the method is computationally safe.
What you're talking about is known as a "known plaintext" attack. With any reasonably secure modern encryption algorithm known plaintext is of essentially no help in an attack. When you're designing an encryption algorithm, you assume that an attacker will have access to an arbitrary amount of known plaintext; if that assists the attacker, the algorithm is considered completely broken by current standards.
In fact, you normally take for granted that the attacker will not only have access to an arbitrary amount of known plaintext, but even an arbitrary amount of chosen plaintext (i.e., they can choose some text, somehow get you to encrypt it, and compare the result to the original. Again, any modern algorithm needs to be immune to this to be considered secure.
Given the Hash and the Encrypted_hash values, and enough of these messages, how easy/hard is it to find out the private key?
This is the scenario of a Known-plaintext attack: you are given many plaintext messages (the hash) and corresponding cipher texts (the encrypted hash) and you want to find out the encryption key.
Modern cryptographic algorithms are designed to withstand this kind of attack, like the RSA algorithm, which is one of the algorithms currently in use for digital signatures.
In other words, it is still extremely difficult to find out the private key. You'd either need an impossible amount of computing power, or you'd need to find a really fast algorithm for factorizing integers, but that would guarantee you lasting fame in the history of mathematics, and hence is even more difficult.
For a more detailed and thorough understanding of cryptography, have a look at the literature, like the Wikipedia pages or Bruce Schneier's Applied Cryptography.
For a perfectly designed hash it is impossible (or rather - there is no easier way than trying every possible input key)
As many will know, one-way encryption is a handy way to encrypt user passwords in databases. That way, even the administrator of the database cannot know a user's password, but will have to take a password guess, encrypt that with the same algorithm and then compare the result with the encrypted password in the database. This means that the process of figuring out the password requires massive amounts of guesses and a lot of processing power.
Seeing that computers just keep getting faster and that mathematicians are still developing these algorithms, I'm wondering which one is the most secure considering modern computing power and encryption techniques.
I've been using MD5 almost exclusively for years now, and I'm wondering if there's something more I should be doing. Should I be contemplating a different algorithm?
Another related question: How long should a field typically be for such an encrypted password? I must admit that I know virtually nothing about encryption, but I'm assuming that an MD5 hash (as an example) can be longer and would presumably take more processing power to crack. Or does the length of the field not matter at all, provided that the encrypted password fits in it in the first place?
Warning: Since this post was written in 2010, GPUs have been widely deployed to brute-force password hashes. Moderately-priced GPUs
can run ten billion MD5s per second. This means that even a
completely-random 8-character alphanumeric password (62 possible
characters) can be brute forced in 6 hours. SHA-1 is only slightly
slower, it'd take one day. Your user's passwords are much weaker, and
(even with salting) will fall at a rate of thousands of passwords per
second. Hash functions are designed to be fast. You don't want this
for passwords. Use scrypt, bcrypt, or PBKDF-2.
MD5 was found to be weak back in 1996, and should not be used anymore for cryptographic purposes. SHA-1 is a commonly used replacement, but has similar problems. The SHA-2 family of hash functions are the current replacement of SHA-1. The members of SHA-2 are individually referred to as SHA-224, SHA-256, SHA-384, and SHA-512.
At the moment, several hash functions are competing to become SHA-3, the next standardised cryptographic hashing algorithm. A winner will be chosen in 2012. None of these should be used yet!
For password hashing, you may also consider using something like bcrypt. It is designed to be slow enough to make large scale brute force attacks infeasible. You can tune the slowness yourself, so it can be made slower when computers are becoming faster.
Warning: bcrypt is based on an older two-way encryption algorithm, Blowfish, for which better alternatives exist today. I do not think that the cryptographic hashing properties of bcrypt are completely understood. Someone correct me if I'm wrong; I have never found a reliable source that discusses bcrypt's properties (other than its slowness) from a cryptographic perspective.
It may be somewhat reassuring that the risk of collisions matters less for password hashing than it does for public-key cryptography or digital signatures. Using MD5 today is a terrible idea for SSL, but not equally disastrous for password hashing. But if you have the choice, simply pick a stronger one.
Using a good hash function is not enough to secure your passwords. You should hash the passwords together with salts that are long and cryptographically random. You should also help your users pick stronger passwords or pass phrases if possible. Longer always is better.
Great question! This page is a good read. In particular, the author claims that MD5 is not appropriate for hashing passwords:
The problem is that MD5 is fast. So are its modern competitors, like SHA1 and SHA256. Speed is a design goal of a modern secure hash, because hashes are a building block of almost every cryptosystem, and usually get demand-executed on a per-packet or per-message basis.
Speed is exactly what you don’t want in a password hash function.
The article then goes on to explain some alternatives, and recommends Bcrypt as the "correct choice" (his words, not mine).
Disclaimer: I have not tried Bcrypt at all. Consider this a friendly recommendation but not something I can back up with my own technical experience.
To increase password strength you should use a wider variety of symbols. If you have 8-10 characters in the password it becomes pretty hard to crack. Although making it longer will make it more secure, only if you use numeric/alphabetic/other characters.
SHA1 is another hashing (one way encryption) algorithm, it is slower, but is has a longer digest. (encoded messsage) (160 bit) where MD5 only has 128 bit.
Then SHA2 is even more secure, but it used less.
salting the password is always an extra level of defense
$salt = 'asfasdfasdf0a8sdflkjasdfapsdufp';
$hashed = md5( $userPassword . $salt );
Seeing that computers just keep getting faster and that mathematicians are still developing these algorithms
RSA encryption is secure in that it relies on a really big number being hard to factor. Eventually, computers will get fast enough to factor the number in a reasonable amount of time. To stay ahead of the curve, you use a bigger number.
However, for most web sites, the purpose of hashing passwords is to make it inconvenient for someone with access to the database to read the password, not to provide security. For that purpose, MD5 is fine1.
The implication here is that if a malicious user gains access to your entire database, they don't need the password. (The lock on the front door won't stop me from coming in the window.)
1 Just because MD5 is "broken" doesn't mean you can just reverse it whenever you want.
Besides being a cryptographically secure one-way function, a good hash function for password protection should be hard to brute force - i.e. slow by design. scrypt is one of the best in that area. From the homepage:
We estimate that on modern (2009) hardware, if 5 seconds are spent computing a derived key, the cost of a hardware brute-force attack against scrypt is roughly 4000 times greater than the cost of a similar attack against bcrypt (to find the same password), and 20000 times greater than a similar attack against PBKDF2.
That said, from commonly available hash functions, doing a few thousand of iterations of anything from the SHA family is pretty reasonable protection for non-critical passwords.
Also, always add a salt to make it impossible to share effort for brute forcing many hashes at a time.
NIST is currently running a contest to select a new hashing algorith, just as they did to select the AES encryption algorithm. So the answer to this question will likely be different in a couple of years.
You can look up the submissions and study them for yourself to see if there's one that you'd like to use.