views:

114

answers:

5

I tried to research this, but there were still some questions left unanswered. I was looking into figuring out how an 8 character password gets turned into a high-bit encryption key. During my research I found articles that would talk about the salt value.

Assume you could get all 256 characters to play with, then an 8-character password would be 64-bits long. So, the remaining 64 bits is simply a salt value. And, correct me if I'm wrong, but this is done so that if someone was going to try to try ALL the possible values (brute force) they'd have to try all 128-bits since even the salt is unknown.

My questions really relate to this 'salt' value:

  1. When someone makes an application, is the salt value hard-coded into it? And if so, can't it be obtained through reverse engineering the executable?
  2. If the salt is generated at random, then I assume it must have some way to duplicate it. So, isn't that function that returns a random salt able to be reverse engineered to force it to duplicate itself to get the salt value?
  3. This might be out of the scope, but if a salt value is generated on a server side (of a client/server relation), then wouldn't it have to be shared with the client so they can decrypt data sent by the server? And, if it's being sent over to the client, can't it be intercepted which makes it useless?
  4. Is there some other method that is used besides this 'salt' value that can turn an 8-character string into a strong encryption key?
+1  A: 

1) Each password is salted differently, and the salt is stored with the hash.

2) It's stored.

3) No, the client never decrypts anything. It sends the password, which the server salts, hashes and compares.

4) Yes, I'll add a few links.

Steven Sudit
See: http://stackoverflow.com/questions/1120381/using-a-hash-of-what-you-are-hashing-as-a-salt/1120410
Steven Sudit
And: http://stackoverflow.com/questions/1111494/are-hashed-and-salted-passwords-secure-against-dictionary-attacks/1111516#1111516
Steven Sudit
The size of the has is independent of the size of the password and the salt. For example, SHA-1 *always* produces a 160-bit hash.
Steven Sudit
Hashing is not encryption because you can't (except for rainbow table attacks on short strings) recover the original.
Steven Sudit
Unless I misunderstand, the OP is asking about generating encryption keys from passphrases, not about hashing and storing passwords.
Nick Johnson
@Nick: It's not so much that you misunderstand as the OP had misunderstood. Salting is only relevant to hashing passwords, not to encryption. The salted hash may well be used as an encryption key, but the salt part is there to protect against rainbow tables, not to enlarge or improve the key.
Steven Sudit
I agree; I guess I ignored the salting bit and not the encryption; yourself and others ignored the encryption bit and not the salting. :)
Nick Johnson
@Nick: Yes, we're both playing guess-the-intent here. It's a popular pastime on this site. The green check next to my answer means I won this round, though.
Steven Sudit
Touche. <!-- -->
Nick Johnson
@Steven Sudit: Actually, the OP is right - salts *are* relevant to Key Derivation Functions, which are used to generate encryption keys. See, for example, PBKDF2: http://en.wikipedia.org/wiki/PBKDF2
caf
@caf: I re-read the question, and you might be right, but then again, maybe not. The problem is that the OP either doesn't understand the issues or isn't good at communicating them, so all of us are left guessing at their intent. If the questioner is sufficiently confused, there might not be a single right answer. Having said that, I'll tell you why I don't think it's about PKKDF2. First, the whole idea of using salt with hashes predates KDF's and is more general. It's been part of the Unix login process for decades. Modern versions of
Steven Sudit
hash-based password security include both the use of cryptographic hashes and strengthening through many rounds of iteration, and this is *still* independent of KDF. KDF does take these algorithms and apply them to key creation. However, the goal is not merely to generate a stronger key (although that's certainly one beneficial effect) but to be able to derive multiple keys from the same secret key without revealing it. In short, you're right that KDF involves both salt and key generation, but I'm not convinced that the OP was thinking of this, or really, of anything this specific.
Steven Sudit
@Nick: You might want to read what caf suggested. They offer a plausible, but -- in my mind -- not entirely convincing, alternative explanation that supports something akin to your interpretation.
Steven Sudit
@Steven Sudit: Well, it's certainly true that we can't really know for sure what the OP is thinking - I was taking their mention of "encryption keys" to mean precisely that (and responding to your comment to @Nick, *"Salting is only relevant to hashing passwords, not to encryption."* which I think was a little over-generalised, since KDFs apply salting in the context of encryption).
caf
@caf: After reading the article you linked to, I followed it to http://en.wikipedia.org/wiki/Key_derivation_function. Here's what I found interesting: it identifies that Unix login algorithm -- `crypt` -- as an *example* of a KDF. But `crypt` is used for authentication, not encryption. Of course, the value a KDF generates *could* be used as an encryption key, but I'm not finding any examples. Could you point me to one, please?
Steven Sudit
Ok, I found some examples. At this point, I think it's fair to say that what we were talking about counts as a KDF, and that KDF's generate something that *could* be used for encryption, but often isn't. In short, we were both right, as was Nick.
Steven Sudit
@Steven Sudit: PBKDF2 is pretty standard in password-based encryption applications - for example, TrueCrypt uses it (see http://www.truecrypt.org/docs/?s=header-key-derivation ). See also the password-based encryption described in PKCS#5: ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-5v2/pkcs5v2_1.pdf
caf
@caf: Actually, I found a bunch of examples at the bottom of that first WP page.
Steven Sudit
+5  A: 

As usual with security-related questions, this answer's going to be a long one.

First, the simple answer.
Q: How does one turn an 8-character string into a 128-bit key?
A: One doesn't.

This is a truthful answer. Now, one that's more appropriate to what you're asking:
A: Create a random 64-bit value, and store it with the password in the database. Now, the password is half the key, and the random value is the other half.

This one is a lie. Here's what you actually do:
A: Hash the password along with a random salt using a method producing 128-bit or longer output. Use 128 bits of that as the key. Store the salt.

Now to address your questions on salt. First off, the purpose of salt is not really to lengthen encryption keys. It is to prevent people building rainbow tables - mappings from hashed to unhashed forms. To see that your encryption is no stronger, just imagine the attacker knows your key-extending algorithm. Now, instead of guessing 128-bit keys, he just guesses your 64-bit password and then uses the same algorithm. Voila. If the salt is unknown to the attacker, yes, you've gained a bit, but they must already have your ciphertexts to attack them, and the salt must be stored in the plain along with the ciphertext. So this is an unlikely scenario.

  1. Salt is random per encryption key.
  2. Random means random. If you are insufficiently random when you use a cryptography algorithm which assumes unpredictable material, you are vulnerable. That's what /dev/random is for - the system entropy pool is very good. Get a better hardware RNG if you're worried.
  3. Yes, if you salted the key, someone needs the salt to decrypt things you encrypted using the salted key's hashed value. No, sending the salt does not necessarily compromise your data; send the salt only to someone who has proved they already have the password, but it's stored in your database next to the ciphertext. As mentioned above, someone needs both the salt and the ciphertext to mount an attack. Again, the purpose of the salt is not to raise the strength of the encryption, it is only to prevent precomputation attacks against your hashes.
  4. There are methods of key extension. But, fundamentally, your protection is only so strong as its weakest link, so to provide 100% unbreakable encryption you will need a one-time-pad (a truly random key as long as the data to be encrypted). In the real world, what is usually done is hashing the password along with a salt to produce unpredictable longer keying material.
Borealid
3) You don't encrypt or decrypt with salt, you hash.
Steven Sudit
@Steven Sudit: I think I edited this before you commented; "you encrypted using the salted key" means "encrypted using a portion of the hashed value of the salted key". I'll clarify again.
Borealid
It's still misleading. Salt is for hashing, not encryption or decryption. Short of brute force, there is no way to recover a password from the hash and salt.
Steven Sudit
A: 
  1. Salts are generally not hardcoded, but they are generated at random, usually server-side, and never communicated to the user.

  2. The salt would be stored in a database, separate from the passwords. The idea is that even if the password hash database is stolen, it would be very difficult to get the actual passwords (you'd have to try a lot of combinations), without having the salts as well. The salts would be generated at random, and different for each user, so even if you found it out for one, you'd still need to find all the others.

  3. The salt is never sent, because the client never decrypts anything. The client sends the password to the server, the server adds the salt (which is randomly generated and stored for each user, and the user never know it).

So basically on this is what happens.

On registration:

  1. User sends password to server.
  2. Server adds a random salt to the password and then hashes it.
  3. The salt and final hash are stored in separate tables.

On login:

  1. User sends password to server.
  2. Server fetches stored hash, and adds it to the password.
  3. Server hashes the password and salt.
  4. If the final hash matches the one in database, the user is logged in.
EdoDodo
2) Salts are typically stored alongside the hashes. They're for protection against rainbow tables, only.
Steven Sudit
As a follow-up, consider that an attack doesn't *need* the salt or the password to log in, just the hash.
Steven Sudit
2) I wasn't entirely sure why Wikipedia said that they are typically stored separately for extra security either... Guess it's one of those cases where Wikipedia is wrong.Also... Why would just the hash be sufficient? The server isn't going to accept just the hash to log in, it will want a password which it can then hash.
EdoDodo
Wikipedia is wrong a lot. In answer to your question, consider this scheme: A web server receives a plaintext password over HTTPS and looks up the user's salt. It combines them and generates a hash. It then passes the hash to the application server with each request. The application server checks it against the database. The benefit is that the web server doesn't have to keep the plaintext password just to keep giving it to the app server, and the app server doesn't have to maintain state, although it does cache. An attacker can hit the app server with just the hash, though.
Steven Sudit
A: 

...Is there some other method that is used besides this 'salt' value that can turn an 8-character string into a strong encryption key?

YES but...

You can compute the hash of that 8-character string:

For example if you need a 256 bit key:

key-256bit = hash(8-character string) //use SHA-256 - very secure key-128bit = hash(8-character string) //use MD5 no more considered secure

"into a strong encryption key?" about strong.... depend how strong you need it because if you use only a 8-character string it mean that you could only create 2^8=256 different hash values and that's an easy task to brute force!!

conclusion: a salt would be of great value!

cheers

Daniel

Daniel Gartmann
8 characters is not 2^8 possibilities. For true arbitrary bytes, 8 bytes is 2^64. For normal alphabetic characters, it's 52^8. That's a fair share more than 256 choices :-P.
Borealid
+1  A: 

The function that turns a password or passphrase into a cryptographic key is called a Key Derivation Function (this might help you searching for more information on the topic). Such functions take a password and a randomly generated salt, and produce a key through a process that is deliberately computationally intensive. To reproduce that key, you must have both the password and the salt - so you are correct, the salt must be stored or transmitted along with the encrypted data.

The reason that Key Derivation Functions use a salt is to increase the work factor for any attacker. If a salt was not used, then a given password will only ever produce one single key. This means that an attacker can easily create a dictionary of keys - one key for each word in his dictionary. If, on the other hand, a 64 bit salt is used then each password can produce ~2**64 different possible keys, which expands the size of the dictionary by the same factor. This essentially makes producing such a dictionary ahead-of-time impossible. Instead, the attacker has to wait until he's seen the salt value, and then start generating keys to test. Since the key derivation function is computationally expensive, this is slow, and he won't be able to get far through his dictionary in a reasonable timeframe.

caf
+1 for recognizing that we were all talking about KDF's.
Steven Sudit