Importance of salt

Importance of salt

Post by vla10 » Fri, 16 Sep 2005 21:51:28


Hello,

I have one question regarding the importance of salt in encryption.

As I understand, the salt is used to prevent dictionary attacks. Also,
it is recommended that the salt isn't always the same, and that it
should be randomly generated for each message. This random salt should
then be stored in the encrypted message, as a prefix for example, so
that it could be retrieved during the decryption.

Now, I don't understand how this helps with dictionary attacks? For
example, if the attacker knows that the first 8 bytes for example are
salt, can't he simply modify his attacking program to include that salt
for each word he retrieves from the dictionary? The assumption here is
that the attacker gets access to the original encryption software as
well as the message.

Secondly, can someone explain how do the increased interations in
PasswordDeriveBytes help?

Thanks for your help,

V.
 
 
 

Importance of salt

Post by Dominick B » Fri, 16 Sep 2005 22:14:27

Hello XXXX@XXXXX.COM ,

first of all - you are mixing some terms here

Encryption - the term salt isn't commonly used here, you may think of an
IV (initialization vector) which is used to start a feedback chain when using
CBC.

but i think you really mean hashing (e.g. for passwords) -

salted hashes are : H(salt+password)

reasons for salting

a) you are not leaking information, e.g. if alice and bob have the same password
- the resulting hash would be the same - not with salted hashes
b) there a tables of pre-computed hashes, so e.g. you encounter a hashed
password of "HJK)((bbnmm" - all you have to do is, look up that table for
the hash and retrieve the clear text value. If you use salted hashes, you
cannot use pre-computed tables, but have to calculate the hash on each try.
this takes time.

By using PasswordDeriveBytes with a high iteration count, you even raise
the bar

a) the attacked does not know the iteration count from looking at the hash
b) it takes even longer now to mount brute force/dictionary attacks - say
a simple hash needs 1 ms - and a iterated hash 1 s to calculate - this makes
password guessing really infeasible

this all depends of course on the password complexity and the computing power
the attackers has at his disposal.

you are basically buying time.

That said - go for salted, iterated hashes by using PasswordDeriveBytes -
or even better the new .NET 2.0 Rfc2898DeriveBytes class.


---------------------------------------
Dominick Baier - DevelopMentor
http://www.yqcomputer.com/

 
 
 

Importance of salt

Post by vla10 » Fri, 16 Sep 2005 23:00:53

ello,

Maybe I wasn't clear enough. Let me try to explain a bit more... I
mentioned salting because I am reffering to a key generation based on a
password (PasswordDeriveBytes class). So, users use plain passwords to
generate a key which is then used for encryption. The salt is used on
that password, which should help prevent the attacker trying to get the
key by using the dictionary.

Now, I understand how this could be helpfull if I use a static salt and
then just transmit the message. The attacker really couldn't use his
dictionary, because he doesn't know the salt. But, what if the attacker
has access to the application that encrypts the messages? He can then
see the static/hardcoded salt and simply use it with his dictionary
when trying out the passwords.

If I want to avoid static salt, I have to generate it somehow, and then
store it so I can use it when decrypting, right? If I store it in a
message, again, whats the point? The attacker can again retrieve the
salt and use it with his dictionary.

I repeat, the assumption is that we are using an publicly available
software for encryption, so the attacker can decompile it or do
whatever he wants with it.

As for the iteration count... if I understood you correctly, all this
does is increase the time that it takes to generate the key from the
password? In other words, if I use 10 iterations to generate the
key/hash for the password, that key can ONLY be generated with the same
password and exactly 10 iterations? The attacker would have to run 10
iterations for each word in his dictionary to get the key, assuming he
even knows the correct iteration count used.

Thanks again for your help,

V.




Dominick Baier [ DevelopMentor ] wrote:

 
 
 

Importance of salt

Post by Dominick B » Fri, 16 Sep 2005 23:49:28

ello XXXX@XXXXX.COM ,

inline


again, the salt helps against precomputed tables


thats always the assumption in crypto. Only the key is secret - nothing else.


yes exactly, but we are talking 50.000 iterations or more - it is really
there to slow down the attacker

That all said - this is not the usual approach for encryption. To minimize
risk when using password based keys:

a) enforce strong, non dictionary passwords
b) encrypt the data using a randomly created key
c) encrypt the random key with the password generated key (add salt if you
like, but does not improve security dramatically IMO)
d) store the encrypted key

now an attacker has 2 choices

a) mount an attack against the encrypted data. infeasible as a full entropy
random key was used
b) mount an attack against the encrypted key. Also hard because it will not
be easy to distinguish between valid and invalid data when trying to decrypt.

makes sense?





 
 
 

Importance of salt

Post by William St » Sat, 17 Sep 2005 09:36:17

, that is all correct. That is the problem with using one-way hash
function for sending passwords. The strength is still based on the strength
of the password. If the password is easy, it will be crack fast via a
dictionary attack. Once it is captured, they can process offline for as
long as it takes. The other issue is your basically creating a password
equivilent. Depending on the what is going on, I can do reply attacks or
maybe even other stuff. What transport tech are you using? WSE, sockets,
Web services, etc.? If you want real security, I would take the next step
into real encryption and key exchange protocol of some kind. WSE, for
example, has a few options built in. I have some other stuff too, but need
to know more about your app as far as what the transport is.

--
William Stacey [MVP]

< XXXX@XXXXX.COM > wrote in message
news: XXXX@XXXXX.COM ...


 
 
 

Importance of salt

Post by vla10 » Sat, 17 Sep 2005 16:53:25

Precomputed tables... now this really sheds some light. :) I didn't
think about the hashed dictionaries. Okay, I see now how any kind of
salting helps against that kind of dictionaries. On the other hand, if
the attacker uses plain dictionaries and computes the hash at runtime
(with my salt), then I can use high number of iterations to slow him
down a bit. Thanks for the explanation... :)

As for your suggestions... this means that the attacker will first have
to try to decrypt a key by lets say dictionary attack, and for each
attempt (each retrieved key) he has to try to decrypt the entire
message with that key. I'm not sure that this is dramatically better
than the original situation where the attacker tries to generate a key
and use that key to decrypt the message. The only advantage that I see
is that in your case, he will spend a bit more time, since he has to
decypt twice. At least thats my understanding, please correct me if i'm
wrong... :)

V.
 
 
 

Importance of salt

Post by vla10 » Sat, 17 Sep 2005 17:25:27

Well, at the moment, I'm just gathering information and clearing few
unclear things... :) But, for our discussion, lets say the application
stores documents and there is a feature to store those documents
securely by encrypting them. The encryption or key storage shoudn't be
machine specific, so we can't use DPAPI or something like that to store
the key. So, we use passwords to generate a key. Users must also be
able to share those documents, provided they share the password as well
(lets ignore the transport of the password at the moment).

This is a basic scenarion. I am aware that the strength of the password
determines the strength of the entire process, and thats why I was
curious how much does the salting help. Not much, as I see... :)

You mentioned key exchange... I thought about asymetric encryption, but
this would mean that a document can be shared only by two people,
right? Also, there is the issue of private key storage. Lets assume
that the machine gets compromised, or that the application resides on
the server, shared computer, or something like that... I would be much
more comfortable knowing that there are no explicit trails of the key
on the machine and that the only way to retrieve it is by a dictionary
attack or by user torture ;)...

V.
 
 
 

Importance of salt

Post by Dominick B » Sat, 17 Sep 2005 17:36:22

Hello XXXX@XXXXX.COM ,

yes - again that slows him down - and give the number of computations necessary
for these kind of attacks, this is an important factor

in general, try to keep the amount of data encrypted with a long term secret
as small as possible.

so what would be a practical solution

0) enforce password complexity (this is the most important step)
1) generate a key from the password, use salting and hashing and iterations
if you like
2) generate a random key
3) encrypt using random key
4) encrypt key using key from password

you should get a copy of "Schneier, Ferguson: Practical Cryptography"

---------------------------------------
Dominick Baier - DevelopMentor
http://www.yqcomputer.com/
 
 
 

Importance of salt

Post by William St » Sat, 17 Sep 2005 18:08:42

So user A has a document and wants to put doc on Server. Doc is encrypted
and sent to server. User B, if allowed access, can download document. Does
the document need to stay encrypted on the server? Does it need to stay
encrypted on the client? Is this the general idea, or something else? Need
a bit more information.

--
William Stacey [MVP]
 
 
 

Importance of salt

Post by vla10 » Sat, 17 Sep 2005 18:27:18

OK, here is a simple use case... You are working on a document, on a
computer that's shared among different users. Doesn't have to be a
server, it can be a laptop, but it doesn't matter, as long as we have
in mind that other people have access to those documents. Upon save,
you are asked for a password, you specify it and the document is
encrypted and then saved. Each time you want to work on it, you
retrieve it in encrypted form to the application, decrypt it, make
changes, encrypt it and save it again... Now you email this document to
5-6 of your friends who know the password. They can open it, decrypt
it, make changes, encrypt it and return it to you. Ignore the usability
aspect of such poor document collaboration :), i'm just illustrating an
example what I would want from the encryption side of it... The
document should always be encrypted, except the time it's open in the
application (for simplicity, let's ignore the fact that the plain text
remains in the memory, or in swap file).

V.
 
 
 

Importance of salt

Post by vla10 » Sat, 17 Sep 2005 18:42:07

Okay, I will consider your approach. Just to be sure that I completely
understand, the increase in time comes from the first computation where
he retrieves a key based on his dictionary. Trying to decrypt with that
retrieved key is the same as if he immediately tried the key he got
based on his dictionary.

Is there a risk in generation of random key? As I understand, the
Random class from the .NET Framework generates pseudo-random numbers
and shouldn't be used in encryption.

Oh, one more thing I see as an advantage of random salt... with it the
resulting encrypted text will always be different even for the same
plain text.

Thanks for the book recommendation as well.

V.
 
 
 

Importance of salt

Post by Dominick B » Sat, 17 Sep 2005 19:15:08

Hello XXXX@XXXXX.COM ,


don't use Random!

IIRC - the SymmetricAlgorithm class has built in key generation. For general
purpose random numbers use the RNGCryptoServiceProvider class.

as i said - there is another golden rule - never use a long term secret (=password)
directly to encrypt bulkloads of data.

---------------------------------------
Dominick Baier - DevelopMentor
http://www.yqcomputer.com/
 
 
 

Importance of salt

Post by vla10 » Sat, 17 Sep 2005 20:35:49

Can you explain a little bit this golder rule of never using a password
derived key on bulkloads of data?

Thanks again.

V.
 
 
 

Importance of salt

Post by William St » Sun, 18 Sep 2005 00:23:40

otya now. In this case, you don't need to store the password anyway, but
in your head. Use PasswordDeriveBytes (or others) to gen your key and iv.
Then use Rijndael/AES to encrypt/decrypt the file. If the wrong pw is
given, the decryption throws an exception. If you forget the pw, your out
of luck. Public knowledge of the source code, does not help them. You can
use the CryptoStream class to help here. Something like:

private static void EncryptFile(string inPath, string outPath,
string password)
{
int blockSize = 4096;
PasswordDeriveBytes pdb = new PasswordDeriveBytes(password,
Encoding.UTF8.GetBytes("salt"));
RNGCryptoServiceProvider rng = new
RNGCryptoServiceProvider(password);
byte[] key = pdb.GetBytes(16);
byte[] iv = pdb.GetBytes(16);
RijndaelManaged rm = new RijndaelManaged();
ICryptoTransform encryptor = rm.CreateEncryptor(key, iv);

using ( FileStream iFs = File.OpenRead(inPath) )
using ( FileStream oFs = File.OpenWrite(outPath))
using ( CryptoStream cs = new CryptoStream(oFs, encryptor,
CryptoStreamMode.Write))
{
byte[] buf = new byte[blockSize];
int read = 0;
while((read = iFs.Read(buf, 0, blockSize)) > 0 )
{
cs.Write(buf, 0, read);
}

cs.FlushFinalBlock();
}
}

private static void DecryptFile(string inPath, string outPath,
string password)
{
int blockSize = 4096;
PasswordDeriveBytes pdb = new PasswordDeriveBytes(password,
Encoding.UTF8.GetBytes("salt"));
byte[] key = pdb.GetBytes(16);
byte[] iv = pdb.GetBytes(16);
RijndaelManaged rm = new RijndaelManaged();
ICryptoTransform decryptor = rm.CreateDecryptor(key, iv);

using ( FileStream iFs = File.OpenRead(inPath) )
using ( FileStream oFs = File.OpenWrite(outPath) )
using ( CryptoStream cs = new CryptoStream(iFs, decryptor,
CryptoStreamMode.Read) )
{
byte[] buf = new byte[blockSize];
int read = 0;
while ( (read = cs.Read(buf, 0, blockSize)) > 0 )
{
oFs.Write(buf, 0, read);
}
}
}
--
William Stacey [MVP]

< XXXX@XXXXX.COM > wrote in message
news: XXXX@XXXXX.COM ...


 
 
 

Importance of salt

Post by Dominick B » Sun, 18 Sep 2005 01:20:21

Hello XXXX@XXXXX.COM ,

there are cryptanalysis methods, which take a different approach than brute
forcing.

By looking at data (and the bigger data the better) you can get the key,
this is especially true if you reuse the key (=password) for different encrypted
data and if the key (=password) is weak.

get the schneier book :)

---------------------------------------
Dominick Baier - DevelopMentor
http://www.yqcomputer.com/