4

I dont know how to use the "salt concept" in my scenario.

Suppose I have a client desktop application that encrypts data for specific users and send it to a remote server. The client application generate a key with PKCS#5, with the user's password and a SALT. The remote desktop must NEVER be in contact with the user's password.

Suppose we generate a random salt for an encryption. The client application can encrypt the data, and sent it to the remote server. If the user try to access his data on another computer, how will it be able to decrypt it since the salt is unknown?

I think that using the same salt all the time (hardcoded in the application) is not a good idea (security by obfuscation is bad).

How can I solve my problem ?

Normand Bedard
  • 2,625
  • 2
  • 19
  • 22

3 Answers3

9

The salt is stored unencrypted along with the encrypted data.

The purpose of a salt is to prevent an attacker from precomputing a dictionary of encrypted passwords. (As in, the attacker spends a year or whatever generating the encrypted form of every word in every language.)

The other purpose of a salt is to make sure that two users will have different encrypted passwords even if their unencrypted passwords are the same.

Neither purpose requires that the salt remain secret.

[update, to elaborate]

See the Wikipedia entry for Salt (cryptography). In particular, read the introductory paragraphs.

The purpose of a salt is to take a non-random input (e.g., user-provided data) and make it random before passing it through a cryptographic function. For this to work, the salt must be randomly generated for each input.

The traditional example is storing encrypted passwords. Most users reliably choose non-random passwords, so without a salt, everyone who chooses "SEKRIT" as a password will wind up with the same encrypted password in the password DB. The solution is to add a random salt before encrypting the password, and then to store it (in plaintext) along with the encrypted password.

Nemo
  • 70,042
  • 10
  • 116
  • 153
  • how does a publicly available salt prevent an attacker from precomputing a dictionary encrypted password? – Heisenbug May 26 '11 at 16:24
  • @0verbose The salt gets added to the password before encryption. So to precompute a dictionary for all words, you would need to combine every possible salt with every possible word. It is easy to make the number of possible salts so large that this is infeasible. – Nemo May 26 '11 at 16:27
  • 1
    @0verbose The salt is _different_ for every password stored in the DB. That is the whole point of the salt! (Did you downvote my answer, which is actually 100% correct?) – Nemo May 26 '11 at 16:31
  • Yes I downvoted it. But if you convince me I'll remove it. Don't be afraid :). Anyway your salt explanation is 100% correct, but which DB are you talking about? it's not saving the password in the server, they are only client side, so what's the purpose of salt in this scenario? – Heisenbug May 26 '11 at 16:35
  • @0verbose Did you read the question? "Suppose I have a client desktop application that encrypts data for specific users and send it to a remote server." I am referring to passwords as an example of "data for specific users", but it could be anything. The principle is the same. – Nemo May 26 '11 at 16:56
  • I do not agree..anyway I'll remove my downvotes..they are too much severe, because your not saying wrong thing in your answer. I wanted just to point out that this isn't a scenario where a salt is necessary to improve security. Of course if differents users share the same client machine this could be a reason for using salts. – Heisenbug May 26 '11 at 17:07
  • @0verbose Thanks. I modified my update to be less snarky. Peace. – Nemo May 26 '11 at 17:38
  • 1
    Nemo is correct. Salt should be public, similar to the initial vector of block ecnryption algorithms. The salt makes the encrypted passphrase harder to decrypt by extending it with random data. – David R Tribble May 26 '11 at 17:41
0

There is an aspect of salting in a distributed environment which is not being covered by any of the answers I have seen thus far. If one's site has multiple databases which need to be kept in sync, how does one guard against a race condition in which a random salt generated on two or more sites near-simultaneously. When the databases are reconciled, how's one to know which salt column for a given row is the correct one?

IMHO, the case for the idea that a salt value needs to be a constantly recalculated random string has not been made against using something like the primary key (PK) for the user row. Before you reply aghast, hear me out.

  • Any reasonable hash function will produce a completely different hash no matter how much the plain text is changes (one or 100 characters added).
  • If you use the PK then the value is independent of all user-provided information.
  • Just like any salting action, the PK-as-salt can be inserted anywhere in the plain text by the algorithm. It does not need to be at the start or end.
  • In a distributed environment, there is no race condition about the salt column because there is no salt column.
  • Using an implied salt like the PK still makes each hash look different even if two folks use the same password. Thus the PK-as-salt idea does what a salt should do without the complications of reconciliations.
Tevya
  • 836
  • 1
  • 10
  • 23
0

If you include the salt with the encrypted data, then the client application on another computer can successfully compute the password hash.

James Johnston
  • 9,264
  • 9
  • 48
  • 76
  • Clarification: don't encrypt the salt. Just send it in plaintext alongside the encrypted data block. – James Johnston May 26 '11 at 16:16
  • What should be the purpose of transmitting a salt in clear ? If an attacker can intercept the traffic, then he can read the salt and the salt itself become unuseful. – Heisenbug May 26 '11 at 16:20
  • 1
    Nemo's answer is a great explanation of why a salt is useful. Suppose an attacker brute-forces or dictionary-attacks the hashed password and successfully discovers the original password. A sufficiently large and random salt prevents this successful result from being immediately applied to other users who used the same password. The attacker is therefore forced to attack each password individually every time. A public plaintext salt does not compromise this. – James Johnston May 26 '11 at 16:30
  • I understand that. But this isn't the same scenario. I mean, password are never transmitted and are not stored into the server. So even if an attaccker discover a client's password having the hash, how would he know the hashes of others clients password? – Heisenbug May 26 '11 at 16:33
  • @0verbose: After further thought: it's necessary to use some type of random data at time of encryption so that the same plaintext input does not ever result in the same ciphertext output every time when using the same password. This is especially important if the beginning of the encrypted data is always the same or very similar (e.g. some type of header). Password salts are one way to add some randomness. Another way would be to use a symmetric encryption algorithm with a random initialization vector transmitted in the clear; you would not need a password salt in this case. – James Johnston May 26 '11 at 16:42
  • @0verbose: to directly answer your question: the attacker cannot know the hashes of other client's passwords IF the encryption algorithm won't generate the same ciphertext twice, for example by using a random IV. – James Johnston May 26 '11 at 16:44
  • I'll also describe an attack if there is not a salt or random IV used at time of encryption: (1) successfully attack one file and discover the password, (2) look for other files that start with the same beginning sequence of bytes as the file I attacked: these would have the same password. If a salt or random IV is used then there won't be any other files with the same beginning sequence of bytes... – James Johnston May 26 '11 at 16:48
  • The point is that only client stores passwords. So there is no transmission of it, and they are not stored anywhere except eventually the client machine. – Heisenbug May 26 '11 at 16:49
  • The risk is not the client storing or transmitting password hashes directly (if it even does this; the OP did not say and the OP could implement the application without permanent storage of the password hash). The attack I described is on the encrypted data itself; may I ask how would you defend this without a salt or random IV? – James Johnston May 26 '11 at 16:54
  • Maybe, I'm not explaining well. What you are saying about salts is correct. Suppose a unix password files stored into a server, an attacker could gain access to it, obtaining all users hashed password, and in that situation a salt is necessary. But this scenario is a bit different: password are not stored anywhere, so the security of the system depends on 1)strongness of the encryption method 2) strogness of the chosen password 3)security of the client machine, if the password is stored locally on the client machine – Heisenbug May 26 '11 at 16:55
  • suppose I'm using AES to locally encrypt the data, with a key derived securely from passphrase(wich attacker don't know), how can you break it ? now suppose for any reason the the key is derived from the passphrase using a salt, and the attaccker know it. How would it increase the security of the encrypted data? – Heisenbug May 26 '11 at 17:05
  • Yes, I understand your point. But, the security of this scenario also needs a nonce: suppose Bob and Alice both encrypt the word "Hello" using the password "bubbles". Without a source of random data, they would both arrive at the same ciphertext. Now suppose Eve discovers that Bob's password is "bubbles". Eve then notes that Alice's ciphertext is the same as Bob's; Eve now knows that Alice's password is "bubbles" as well. To reiterate my previous question: how do you plan on preventing Eve from discovering what Alice's password and data were based on the compromise of Bob's password? – James Johnston May 26 '11 at 17:07
  • A typical AES scheme will use a scheme like CBC: http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 AES block sizes are 16 bytes: i.e. you can only encrypt 16 bytes at a time. CBC lets you securely chain together multiple blocks. But, if the first 16 bytes are always the same then the contrived Alice/Bob example I gave is not so contrived any more... Notice the page says you need a random IV for CBC to work well - it is not just me saying this... If a new salt is chosen every time the user encrypts something, then the salt functions as an IV. – James Johnston May 26 '11 at 17:12
  • If a user changes his password, the whole system does not work anymore. What if a symmetric AES key is generated randomly and is encrypted by a key generated by PKCS#5 algo (with salt and user`s password)? Does the remote server had to keep the encrypted AES key AND the initial salt used ? – Normand Bedard May 26 '11 at 17:23
  • @user374576: your idea sounds good. If the password changes then decrypt the AES key and re-encrypt it with the new password. As part of this, the salt for the old password has to be stored with the encrypted AES key to facilitate decryption by the client. On a password change, I would: (1) download old salt & encrypted AES key from server, (2) decrypt AES key using the user's old password, (3) encrypted AES key using the user's new password and a new, random salt, (4) send both new salt & encrypted AES key to the server. – James Johnston May 26 '11 at 17:35
  • Since the salt is used to generate the key used to encrypt the AES key, I suppose the salt is generated only one time? The same salt will be used to create the encryption key used to encrypt/decrypt the single and unique AES key? – Normand Bedard May 26 '11 at 18:01
  • Right - when the user sets a new password, the salt is made using a random number generator suitable for cryptographic use (not your average runtime rand() type of function). This would be stored alongside the encrypted AES key. If the user is just trying to decrypt data, you'd use the existing salt and the password they entered to generate your decryption key. – James Johnston May 26 '11 at 18:58