[android-developers] Re: hash functions
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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