[android-developers] Re: hash functions

2011-05-12 Thread Bob Kerns
Ah, I see your confusion, and I should have been more careful to forestall 
it.

That's not what is meant here by a dictionary attack. What you describe is 
what is defended against by the iteration.

The dictionary attack defended by a salt is where a *pre-computed* 
dictionary of keys for likely passwords is constructed. What the salt does 
is explode the size of that dictionary, basically making it infeasible to 
pre-compute the hashes for entries in a dictionary. Otherwise, you could 
bypass the iteration cost, by distributing the cost over a large number of 
attacks. Then you just search your dictionary for a key that fits, and do no 
key construction at all during the attack.

Certainly iteration can be expensive! That's the whole point, and why it's 
not specified how many iterations are appropriate. You select the iteration 
count to determine how long the key computation should take.

But the vast majority of the cost of doing a rekey? That would either 
imply a huge iteration count, or a small amount of data to be re-encrypted. 
In the former case -- don't do that. In the latter case -- it doesn't 
matter. Actually, it probably doesn't matter anyway, as rekeying is 
generally an administrative operation, not part of the overall performance 
of the system. But since the key is derived on first use, the absolute 
(clock) time consumed will be relevant there. The default iteration count 
for SQLCipher is 4000, which is pretty typical. But on slow hardware, I 
suppose that could be too high. In which case -- set it to a lower value.

Typically, 100ms computation time after a user supplies a password is not 
going to be noticed, while 1000ms will. Balance that against the resources 
available to an attacker (which will vary by scenario and with the 
advancement of computing power).


On Wednesday, May 11, 2011 5:27:30 PM UTC-7, DanH wrote:

 Salt doesn't prevent dictionary attacks at all.  If I know that the 
 password is an 6-character alpha then I can try all combos of that, 
 dictionary or otherwise, regardless of how salted the encryption is. 

 I've seen iteration add considerable overhead.  In one SqlCipher 
 implementation iteration was the vast majority of the CPU costs of 
 doing a rekey. 

 On May 10, 11:13 pm, Bob Kerns r@acm.org wrote: 
  I think you missed part of what I was saying. It's important, so let me 
 try 
  to be more clear. 
  
  Each of the two components does a different job. 
  
  The salt prevents dictionary attacks, by expanding the space of 
 dictionaries 
  by the size of the salt (say, 2^128 or whatever you use.) 
  
  The protection against trial-and-error cracking is where the iteration 
 comes 
  in -- you make it take a long time to generate the final key from the 
  password. 
  
  The salt isn't (in this context) to prevent plaintext attacks, but 
  dictionary attacks, which are EXTREMELY relevant to this case. 
  
  Increasing the length of a weak password has surprisingly little effect 
 in 
  the real world. Some, definitely, but not on the scale you'd expect from 
  sheer length. And in a lot of contexts, you really can't force users to 
 use 
  such long passwords -- the password I'm forced to use on my phone for 
  corporate security reasons is very very close to to rendering my phone 
  unusable. 
  
  The overhead that the iteration adds to the normal path is generally 
  negligible, because it's done on the client side, once. You can tune the 
  iteration count to balance the performance requirements vs the security 
  requirements. If 100 ms is acceptable, then choose your iteration count 
  accordingly, and you will limit the attacker to 10 attempts per second 
 per 
  CPU, which certainly beats 1000 attempts per second per CPU. 
  
  On Tuesday, May 10, 2011 8:35:00 PM UTC-7, DanH wrote: 
  
   Of course, hashing a password, per se, doesn't really make it any 
   stronger.  And doing things like using a salt don't do much if the 
   concern is simple trial-and-error cracking of a single encrypted 
   message (unless you're relying on security by obscurity).  Salting 
   does help prevent known plaintext attacks and signature spoofing, but 
   those are not likely to be problems in low-volume messaging. 
   Iterating on an expensive hash can help discourage the trial-and-error 
   cracking attack, but it can add considerable overhead to the normal 
   path, and simply increasing the length of a weak password would be far 
   more effective. 
  
   On May 10, 5:34 pm, Bob Kerns r@acm.org wrote: 
The fundamental problem with starting with a human-managed password 
 is 
   that 
there is not a lot of entropy -- the possible values are not 
 distributed 
over a huge range, compared to what an attacker could try with 
trial-and-error. 
  
So just doing SHA1 or SHA256 for that matter, is not sufficient for a 

   strong 
key generation algorithm. 
  
The first thing you need to address are dictionary attacks, where the 

  

[android-developers] Re: hash functions

2011-05-11 Thread gjs
Hi,

1st link was to simply show mention of longer bit length SHA
algorithms in Android SDK, not how to go about effectively using them,
which usually involves 'salt' and other measures as other have
discussed here and else where.

MD5 (128 bits) is 'weaker' than SHA1 (160 bits) only by virtue of
having less bits, without seeking to start an argument both are
'broken/have collisions' in theory/practice anyway, hence SHA3 contest
http://csrc.nist.gov/groups/ST/hash/sha-3/index.html

http://www.schneier.com/blog/archives/2005/06/more_md5_collis.html
http://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html
http://www.schneier.com/blog/archives/2011/02/nist_defines_ne.html

Regards

On May 10, 5:52 pm, Nikolay Elenkov nikolay.elen...@gmail.com wrote:
 On Tue, May 10, 2011 at 3:59 PM, gjs garyjamessi...@gmail.com wrote:
 http://developer.android.com/reference/java/security/spec/MGF1Paramet...

  SHA256, 384, 512

 What does the mask generation function has to do with this?
 Don't just paste random links.



 http://developer.android.com/reference/java/security/MessageDigest.html

  MD5 is weaker than SHA

 Qualify 'weaker'. See above.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: hash functions

2011-05-11 Thread Brill Pappin
Here you go.
This is some old code for a fairly light encryption job. You might want to 
adjust the algorithm a bit to use at least SHA (also maybe not use DES).
I think I'd also make the salt mutable based on a second input, but it 
really depends on how much you care about protecting what your encrypting.

- Brill

import javax.crypto.Cipher;

import javax.crypto.SecretKey;

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.PBEKeySpec;

import javax.crypto.spec.PBEParameterSpec;


import android.util.Log;


public class PBECypher {

private static final String TAG = PBECypher;

private final static String HEX = 0123456789ABCDEF;

private Cipher encryptCipher;

private Cipher decryptCipher;


 public PBECypher(char[] password) {

super();

initCiphers(password);

}


 private void initCiphers(char password[]) {

PBEKeySpec pbeKeySpec;

PBEParameterSpec pbeParamSpec;

SecretKeyFactory keyFac;

byte[] salt = { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,

(byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 };

int count = 20;

pbeParamSpec = new PBEParameterSpec(salt, count);

pbeKeySpec = new PBEKeySpec(password);

try {

keyFac = SecretKeyFactory.getInstance(PBEWithMD5AndDES);

SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

encryptCipher = Cipher.getInstance(PBEWithMD5AndDES);

decryptCipher = Cipher.getInstance(PBEWithMD5AndDES);

encryptCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

decryptCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);

} catch (Exception e) {

Log.v(TAG, e.toString());

}

}


 public byte[] encrypt(byte[] decrypted) throws Exception {

byte[] output = encryptCipher.doFinal(decrypted);

return output;

}


 public byte[] decrypt(byte[] encrypted) throws Exception {

byte[] decrypted = decryptCipher.doFinal(encrypted);

return decrypted;

}


 public String encryptString(String decrypted) throws Exception {

byte[] input = decrypted.getBytes(UTF-8);

return toHexFromByte(encrypt(input));

}


 public String decryptString(String encrypted) throws Exception {

byte[] input = toByteFromHex(encrypted);

return new String(decrypt(input), UTF-8);

}


 public static String toHex(String txt) {

return toHexFromByte(txt.getBytes());

}


 public static String fromHex(String hex) {

return new String(toByteFromHex(hex));

}


 public static byte[] toByteFromHex(String hexString) {

int len = hexString.length() / 2;

byte[] result = new byte[len];

for (int i = 0; i  len; i++) {

result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),

16).byteValue();

}

return result;

}


 public static String toHexFromByte(byte[] buf) {

if (buf == null) {

return ;

}

StringBuffer result = new StringBuffer(2 * buf.length);

for (int i = 0; i  buf.length; i++) {

appendHex(result, buf[i]);

}

return result.toString();

}


 private static void appendHex(StringBuffer sb, byte b) {

sb.append(HEX.charAt((b  4)  0x0f)).append(HEX.charAt(b  0x0f));

}

}

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Re: [android-developers] Re: hash functions

2011-05-11 Thread Brill Pappin
Nod to Bob on not doing it yourself... there is no reason to do so.
There is nothing worse than your masterpiece of unbreakable encryption that 
only you don't know is full of holes.

I've seen some pretty silly things done in the name of extra encryption 
and it's just not worth your time.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

[android-developers] Re: hash functions

2011-05-11 Thread Brill Pappin
Arg, just reread your opost.
All you want is a hash (as in a one way hash)?
The encryption decryption confused me ;)

SHA is likely adequate... simply do a google search for java sha and 
you'll find a tone of examples on digesting a string... most of them will 
work in Android.

- Brill

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

[android-developers] Re: hash functions

2011-05-11 Thread Brill Pappin
Ahh... love this little library.

See:
http://www.jasypt.org/howtoencryptuserpasswords.html

- Brill

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

[android-developers] Re: hash functions

2011-05-11 Thread Bob Kerns
No, he thinks he just wants a hash to construct a key from a password.

Probably, he just wants to encrypt / decrypt, in which case, your code is 
mostly adequate, except for a serious flaw, of a constant salt. A constant 
salt defeats the purpose; you can construct a perfectly fine dictionary of 
pre-computed keys for any fixed salt.

What you want to do is to generate a random salt, and prepend it to your 
encrypted result. Then to decrypt, extract it again, and use that for 
decryption. The reasons are laid out in the link you post in the next 
message.

And don't use MD5. It may be good enough, but there's really no reason to 
do so, because at least SHA-1 is available.

Anyway, he probably really just wants to encrypt and decrypt, and aside from 
the above flaws, you probably gave him just what he needs.


On Wednesday, May 11, 2011 12:09:16 AM UTC-7, Brill Pappin wrote:

 Arg, just reread your opost.
 All you want is a hash (as in a one way hash)?
 The encryption decryption confused me ;)

 SHA is likely adequate... simply do a google search for java sha and 
 you'll find a tone of examples on digesting a string... most of them will 
 work in Android.

 - Brill


-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

[android-developers] Re: hash functions

2011-05-11 Thread DanH
Salt doesn't prevent dictionary attacks at all.  If I know that the
password is an 6-character alpha then I can try all combos of that,
dictionary or otherwise, regardless of how salted the encryption is.

I've seen iteration add considerable overhead.  In one SqlCipher
implementation iteration was the vast majority of the CPU costs of
doing a rekey.

On May 10, 11:13 pm, Bob Kerns r...@acm.org wrote:
 I think you missed part of what I was saying. It's important, so let me try
 to be more clear.

 Each of the two components does a different job.

 The salt prevents dictionary attacks, by expanding the space of dictionaries
 by the size of the salt (say, 2^128 or whatever you use.)

 The protection against trial-and-error cracking is where the iteration comes
 in -- you make it take a long time to generate the final key from the
 password.

 The salt isn't (in this context) to prevent plaintext attacks, but
 dictionary attacks, which are EXTREMELY relevant to this case.

 Increasing the length of a weak password has surprisingly little effect in
 the real world. Some, definitely, but not on the scale you'd expect from
 sheer length. And in a lot of contexts, you really can't force users to use
 such long passwords -- the password I'm forced to use on my phone for
 corporate security reasons is very very close to to rendering my phone
 unusable.

 The overhead that the iteration adds to the normal path is generally
 negligible, because it's done on the client side, once. You can tune the
 iteration count to balance the performance requirements vs the security
 requirements. If 100 ms is acceptable, then choose your iteration count
 accordingly, and you will limit the attacker to 10 attempts per second per
 CPU, which certainly beats 1000 attempts per second per CPU.

 On Tuesday, May 10, 2011 8:35:00 PM UTC-7, DanH wrote:

  Of course, hashing a password, per se, doesn't really make it any
  stronger.  And doing things like using a salt don't do much if the
  concern is simple trial-and-error cracking of a single encrypted
  message (unless you're relying on security by obscurity).  Salting
  does help prevent known plaintext attacks and signature spoofing, but
  those are not likely to be problems in low-volume messaging.
  Iterating on an expensive hash can help discourage the trial-and-error
  cracking attack, but it can add considerable overhead to the normal
  path, and simply increasing the length of a weak password would be far
  more effective.

  On May 10, 5:34 pm, Bob Kerns r@acm.org wrote:
   The fundamental problem with starting with a human-managed password is
  that
   there is not a lot of entropy -- the possible values are not distributed
   over a huge range, compared to what an attacker could try with
   trial-and-error.

   So just doing SHA1 or SHA256 for that matter, is not sufficient for a
  strong
   key generation algorithm.

   The first thing you need to address are dictionary attacks, where the
   attacker can pre-compute a large dictionary of keys from likely
  passwords.
   Here, you can inject randomness into the process. What you do is to start

   with a large random number, termed a 'salt'. This is not a secret --
  you'll
   save it away in cleartext somehow, and then combine it with the user's
   password. While the attacker could afford to build a dictionary of keys
   based on passwords, a dictionary of possible salt values + passwords
  would
   be vastly larger.

   The other thing you need to do is to protect against trial-and-error
   attacks. To do this, what you do is make it expensive enough to compute
  the
   key that an attacker simply couldn't try enough to get anywhere. The
  usual
   way of doing this is to iterate some expensive function -- such as SHA1.
   More precisely, you iterate this:

   hash = f(hash)

   where f is some function that is expensive, and does not collapse the
  space
   of possible values into some smaller set. One way to accomplish this
  would
   be:
   f(hash) = hash xor sha1(hash).

   I went with SHA1 above, because I want to tie this to PBKDF2, which
  Nikolay
   referenced.

   What I outline above is roughly what PBKDF2 does for you. You can read
  the
   full details in rfc2898 http://tools.ietf.org/html/rfc2898, and I
   encourage you to do so. I did skip over a lot of detail to focus on the
   motivation and approach.

   So there are basically two parameters -- the salt (selected randomly) and

   the iteration count (selected to make it expensive but not too
  expensive).
    iOS4 uses I believe something like 1 iterations. Blackberry used 1,
  and
   was seriously pwned as a result.

   Together, these compensate for the narrow range of human-generated
   passwords.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to

[android-developers] Re: hash functions

2011-05-10 Thread gjs
http://developer.android.com/reference/java/security/spec/MGF1ParameterSpec.html

SHA256, 384, 512

http://developer.android.com/reference/java/security/MessageDigest.html

MD5 is weaker than SHA

On May 10, 3:52 pm, pasamblue1 parulcha...@gmail.com wrote:
 I am developing an android application for encryption decryption of
 messages. I need some hash algorithm to generate key from password. I
 am using SHA1 for the same. Not sure if it is good to use it for
 security reasons. Is there any other algorithm to be used as hash
 function.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


Re: [android-developers] Re: hash functions

2011-05-10 Thread Nikolay Elenkov
On Tue, May 10, 2011 at 3:59 PM, gjs garyjamessi...@gmail.com wrote:
 http://developer.android.com/reference/java/security/spec/MGF1ParameterSpec.html

 SHA256, 384, 512

What does the mask generation function has to do with this?
Don't just paste random links.


 http://developer.android.com/reference/java/security/MessageDigest.html

 MD5 is weaker than SHA


Qualify 'weaker'. See above.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: hash functions

2011-05-10 Thread pasamblue1
How about PBKDF2. This one is as per FIPs standard.
Is SHA1 also a standard from FIPs.

On May 10, 12:52 pm, Nikolay Elenkov nikolay.elen...@gmail.com
wrote:
 On Tue, May 10, 2011 at 3:59 PM, gjs garyjamessi...@gmail.com wrote:
 http://developer.android.com/reference/java/security/spec/MGF1Paramet...

  SHA256, 384, 512

 What does the mask generation function has to do with this?
 Don't just paste random links.



 http://developer.android.com/reference/java/security/MessageDigest.html

  MD5 is weaker than SHA

 Qualify 'weaker'. See above.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: hash functions

2011-05-10 Thread DanH
For your purposes any standard hash algorithm that produces the
desired number of bits should be fine.  The weakness of hash
algorithms has to do mostly with the ability to counterfeit data
that produces a given hash value -- this is an important consideration
when the hash is being used in a digital signature algorithm, but
not important if you're just hashing, say, an alpha password to create
a key.

On May 10, 12:52 am, pasamblue1 parulcha...@gmail.com wrote:
 I am developing an android application for encryption decryption of
 messages. I need some hash algorithm to generate key from password. I
 am using SHA1 for the same. Not sure if it is good to use it for
 security reasons. Is there any other algorithm to be used as hash
 function.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: hash functions

2011-05-10 Thread Bob Kerns
The fundamental problem with starting with a human-managed password is that 
there is not a lot of entropy -- the possible values are not distributed 
over a huge range, compared to what an attacker could try with 
trial-and-error.

So just doing SHA1 or SHA256 for that matter, is not sufficient for a strong 
key generation algorithm.

The first thing you need to address are dictionary attacks, where the 
attacker can pre-compute a large dictionary of keys from likely passwords. 
Here, you can inject randomness into the process. What you do is to start 
with a large random number, termed a 'salt'. This is not a secret -- you'll 
save it away in cleartext somehow, and then combine it with the user's 
password. While the attacker could afford to build a dictionary of keys 
based on passwords, a dictionary of possible salt values + passwords would 
be vastly larger.

The other thing you need to do is to protect against trial-and-error 
attacks. To do this, what you do is make it expensive enough to compute the 
key that an attacker simply couldn't try enough to get anywhere. The usual 
way of doing this is to iterate some expensive function -- such as SHA1. 
More precisely, you iterate this:

hash = f(hash)

where f is some function that is expensive, and does not collapse the space 
of possible values into some smaller set. One way to accomplish this would 
be:
f(hash) = hash xor sha1(hash).

I went with SHA1 above, because I want to tie this to PBKDF2, which Nikolay 
referenced.

What I outline above is roughly what PBKDF2 does for you. You can read the 
full details in rfc2898 http://tools.ietf.org/html/rfc2898, and I 
encourage you to do so. I did skip over a lot of detail to focus on the 
motivation and approach.

So there are basically two parameters -- the salt (selected randomly) and 
the iteration count (selected to make it expensive but not too expensive). 
 iOS4 uses I believe something like 1 iterations. Blackberry used 1, and 
was seriously pwned as a result.

Together, these compensate for the narrow range of human-generated 
passwords.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Re: [android-developers] Re: hash functions

2011-05-10 Thread Bob Kerns
https://www.kb.cert.org/vuls/id/836068

https://www.kb.cert.org/vuls/id/836068Nothing new should have been using 
MD5 for a looong time, and people need to know to stay away from it.

Fake SSL certs that exploit this have been produced. It's not just a 
theoretical concern.

On Tuesday, May 10, 2011 12:52:24 AM UTC-7, Nikolay Elenkov wrote:

 On Tue, May 10, 2011 at 3:59 PM, gjs garyjam...@gmail.com wrote:

  http://developer.android.com/reference/java/security/MessageDigest.html
 
  MD5 is weaker than SHA
 

 Qualify 'weaker'. See above.



-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Re: [android-developers] Re: hash functions

2011-05-10 Thread Nikolay Elenkov
On Wed, May 11, 2011 at 8:32 AM, Bob Kerns r...@acm.org wrote:
 https://www.kb.cert.org/vuls/id/836068
 Nothing new should have been using MD5 for a looong time, and people need to
 know to stay away from it.
 Fake SSL certs that exploit this have been produced. It's not just a
 theoretical concern.

I know :) But as with most things, one shouldn't avoid it just because
one heard somewhere that it's 'weaker'. At least a bit of research
is needed, that's what my comment was meant to say. And the
MessageDigest class reference was not exactly relevant.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: hash functions

2011-05-10 Thread DanH
Of course, hashing a password, per se, doesn't really make it any
stronger.  And doing things like using a salt don't do much if the
concern is simple trial-and-error cracking of a single encrypted
message (unless you're relying on security by obscurity).  Salting
does help prevent known plaintext attacks and signature spoofing, but
those are not likely to be problems in low-volume messaging.
Iterating on an expensive hash can help discourage the trial-and-error
cracking attack, but it can add considerable overhead to the normal
path, and simply increasing the length of a weak password would be far
more effective.

On May 10, 5:34 pm, Bob Kerns r...@acm.org wrote:
 The fundamental problem with starting with a human-managed password is that
 there is not a lot of entropy -- the possible values are not distributed
 over a huge range, compared to what an attacker could try with
 trial-and-error.

 So just doing SHA1 or SHA256 for that matter, is not sufficient for a strong
 key generation algorithm.

 The first thing you need to address are dictionary attacks, where the
 attacker can pre-compute a large dictionary of keys from likely passwords.
 Here, you can inject randomness into the process. What you do is to start
 with a large random number, termed a 'salt'. This is not a secret -- you'll
 save it away in cleartext somehow, and then combine it with the user's
 password. While the attacker could afford to build a dictionary of keys
 based on passwords, a dictionary of possible salt values + passwords would
 be vastly larger.

 The other thing you need to do is to protect against trial-and-error
 attacks. To do this, what you do is make it expensive enough to compute the
 key that an attacker simply couldn't try enough to get anywhere. The usual
 way of doing this is to iterate some expensive function -- such as SHA1.
 More precisely, you iterate this:

 hash = f(hash)

 where f is some function that is expensive, and does not collapse the space
 of possible values into some smaller set. One way to accomplish this would
 be:
 f(hash) = hash xor sha1(hash).

 I went with SHA1 above, because I want to tie this to PBKDF2, which Nikolay
 referenced.

 What I outline above is roughly what PBKDF2 does for you. You can read the
 full details in rfc2898 http://tools.ietf.org/html/rfc2898, and I
 encourage you to do so. I did skip over a lot of detail to focus on the
 motivation and approach.

 So there are basically two parameters -- the salt (selected randomly) and
 the iteration count (selected to make it expensive but not too expensive).
  iOS4 uses I believe something like 1 iterations. Blackberry used 1, and
 was seriously pwned as a result.

 Together, these compensate for the narrow range of human-generated
 passwords.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


Re: [android-developers] Re: hash functions

2011-05-10 Thread Nikolay Elenkov
On Wed, May 11, 2011 at 7:34 AM, Bob Kerns r...@acm.org wrote:

 More precisely, you iterate this:
 hash = f(hash)
 where f is some function that is expensive, and does not collapse the space
 of possible values into some smaller set. One way to accomplish this would
 be:
 f(hash) = hash xor sha1(hash).
 I went with SHA1 above, because I want to tie this to PBKDF2, which Nikolay
 referenced.

Do you mean you implemented this yourself? Not that it's too hard to do, but
Android has the Bouncy Castle JCE provider, so all you have to do is usually:

SecretKeyFactory factory = SecretKeyFactory.getInstance(KEYGEN_ALGORITHM)
KeySpec keySpec = new PBEKeySpec(password, salt, numInterations,  keyLen);
SecretKey key = factory.generateSecret(keySpec);

where KEYGEN_ALGORITHM is a supported PBE algorithm.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


Re: [android-developers] Re: hash functions

2011-05-10 Thread Nikolay Elenkov
On Wed, May 11, 2011 at 12:35 PM, DanH danhi...@ieee.org wrote:
 Of course, hashing a password, per se, doesn't really make it any
 stronger.  And doing things like using a salt don't do much if the
 concern is simple trial-and-error cracking of a single encrypted
 message (unless you're relying on security by obscurity).

If the attacker doesn't know that the key is derived from a password,
may be not. But since it's a reasonable assumption that they have
seen the application, which has an 'input password to encrypt message'
dialog, they probably do. And if so, it's trivial to take a dictionary and
compute all keys derivable from it. Then cracking the message becomes
really easy. Adding a salt and multiple iterations does make this
considerably more expensive/harder.

(BTW, the usual term is actually 'brute force attack', not 'trial-and-error'.)

 Iterating on an expensive hash can help discourage the trial-and-error
 cracking attack, but it can add considerable overhead to the normal
 path, and simply increasing the length of a weak password would be far
 more effective.

No. Increasing a *human selected* password from 6 to say 12 characters,
wouldn't really increase the entropy, people are just likely to pick a longer
word or append '123' to their usual password. Plus the overhead of deriving
a password is hardly 'considerable', especially considering that it will be
done only once on encryption/decryption.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: hash functions

2011-05-10 Thread Bob Kerns
I think you missed part of what I was saying. It's important, so let me try 
to be more clear.

Each of the two components does a different job.

The salt prevents dictionary attacks, by expanding the space of dictionaries 
by the size of the salt (say, 2^128 or whatever you use.)

The protection against trial-and-error cracking is where the iteration comes 
in -- you make it take a long time to generate the final key from the 
password.

The salt isn't (in this context) to prevent plaintext attacks, but 
dictionary attacks, which are EXTREMELY relevant to this case.

Increasing the length of a weak password has surprisingly little effect in 
the real world. Some, definitely, but not on the scale you'd expect from 
sheer length. And in a lot of contexts, you really can't force users to use 
such long passwords -- the password I'm forced to use on my phone for 
corporate security reasons is very very close to to rendering my phone 
unusable.

The overhead that the iteration adds to the normal path is generally 
negligible, because it's done on the client side, once. You can tune the 
iteration count to balance the performance requirements vs the security 
requirements. If 100 ms is acceptable, then choose your iteration count 
accordingly, and you will limit the attacker to 10 attempts per second per 
CPU, which certainly beats 1000 attempts per second per CPU.

On Tuesday, May 10, 2011 8:35:00 PM UTC-7, DanH wrote:

 Of course, hashing a password, per se, doesn't really make it any 
 stronger.  And doing things like using a salt don't do much if the 
 concern is simple trial-and-error cracking of a single encrypted 
 message (unless you're relying on security by obscurity).  Salting 
 does help prevent known plaintext attacks and signature spoofing, but 
 those are not likely to be problems in low-volume messaging. 
 Iterating on an expensive hash can help discourage the trial-and-error 
 cracking attack, but it can add considerable overhead to the normal 
 path, and simply increasing the length of a weak password would be far 
 more effective. 

 On May 10, 5:34 pm, Bob Kerns r@acm.org wrote: 
  The fundamental problem with starting with a human-managed password is 
 that 
  there is not a lot of entropy -- the possible values are not distributed 
  over a huge range, compared to what an attacker could try with 
  trial-and-error. 
  
  So just doing SHA1 or SHA256 for that matter, is not sufficient for a 
 strong 
  key generation algorithm. 
  
  The first thing you need to address are dictionary attacks, where the 
  attacker can pre-compute a large dictionary of keys from likely 
 passwords. 
  Here, you can inject randomness into the process. What you do is to start 

  with a large random number, termed a 'salt'. This is not a secret -- 
 you'll 
  save it away in cleartext somehow, and then combine it with the user's 
  password. While the attacker could afford to build a dictionary of keys 
  based on passwords, a dictionary of possible salt values + passwords 
 would 
  be vastly larger. 
  
  The other thing you need to do is to protect against trial-and-error 
  attacks. To do this, what you do is make it expensive enough to compute 
 the 
  key that an attacker simply couldn't try enough to get anywhere. The 
 usual 
  way of doing this is to iterate some expensive function -- such as SHA1. 
  More precisely, you iterate this: 
  
  hash = f(hash) 
  
  where f is some function that is expensive, and does not collapse the 
 space 
  of possible values into some smaller set. One way to accomplish this 
 would 
  be: 
  f(hash) = hash xor sha1(hash). 
  
  I went with SHA1 above, because I want to tie this to PBKDF2, which 
 Nikolay 
  referenced. 
  
  What I outline above is roughly what PBKDF2 does for you. You can read 
 the 
  full details in rfc2898 http://tools.ietf.org/html/rfc2898, and I 
  encourage you to do so. I did skip over a lot of detail to focus on the 
  motivation and approach. 
  
  So there are basically two parameters -- the salt (selected randomly) and 

  the iteration count (selected to make it expensive but not too 
 expensive). 
   iOS4 uses I believe something like 1 iterations. Blackberry used 1, 
 and 
  was seriously pwned as a result. 
  
  Together, these compensate for the narrow range of human-generated 
  passwords.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Re: [android-developers] Re: hash functions

2011-05-10 Thread Bob Kerns
No -- I've always been fortunate enough to have Bouncy Castle or similar 
packages available, and haven't had to implement it myself. I *have* 
implemented similar things in the distant past before we knew quite as much 
about the problems and solutions. I.e. with a salt, with an insecure hash 
function, without iteration. We're talking pre-RSA here. (I have an original 
copy of the original RSA paper, which I obtained prior to the NSA's attempt 
at getting it banned!).

My goal wasn't to explain how to code it, but rather how it works, so you 
understand, for example, the role of the salt (so you use a SecureRandom to 
generate it, not some constant!) and the role of the iteration count, so you 
know how to set that to something reasonable -- i.e., not 1 like on the 
Blackberry.

I highly recommend not coding it yourself, unless you're undertaking a 
serious study of cryptography. Otherwise, it's a waste of time and potential 
source of bugs, even though it's not all that complicated.

On Tuesday, May 10, 2011 9:00:58 PM UTC-7, Nikolay Elenkov wrote:

 On Wed, May 11, 2011 at 7:34 AM, Bob Kerns r...@acm.org wrote:

  More precisely, you iterate this:
  hash = f(hash)
  where f is some function that is expensive, and does not collapse the 
 space
  of possible values into some smaller set. One way to accomplish this 
 would
  be:
  f(hash) = hash xor sha1(hash).
  I went with SHA1 above, because I want to tie this to PBKDF2, which 
 Nikolay
  referenced.

 Do you mean you implemented this yourself? Not that it's too hard to do, 
 but
 Android has the Bouncy Castle JCE provider, so all you have to do is 
 usually:

 SecretKeyFactory factory = SecretKeyFactory.getInstance(KEYGEN_ALGORITHM)
 KeySpec keySpec = new PBEKeySpec(password, salt, numInterations,  keyLen);
 SecretKey key = factory.generateSecret(keySpec);

 where KEYGEN_ALGORITHM is a supported PBE algorithm.



-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en