0

Check update#1

This logic is a candidate for a authentication procedure, done by simple HTTP requests:

  • I'm sending: userName + encrypted_userName (encrypted_userName is actually the encrypted result of userName, done using AES & as key i use the md5 hash of the password). NOTE: I'm not sending the md5 hashed Password.
  • on the server I'm comparing: encrypted_userName with own_encrypted_userName (since on server i have access to full info on user, i calculate own encrypted_userName).

Question: is this a security flaw? Say bad guy captures full HTTP request, can he extract password from this 2 infos?

CODE DETAILS, if needed:

private static Cipher getCipher(String key, int mode) throws Exception{
     byte[] rawKey = getRawKey(key.getBytes("UTF-8"));
     SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
     Key key2 = skeySpec;
     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
     cipher.init(mode, key2);
     return cipher;
}

private static byte[] getRawKey(byte[] seed) throws Exception {
/*  BEFORE:
     KeyGenerator kgen = KeyGenerator.getInstance("AES");
     SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
     sr.setSeed(seed);
     kgen.init(128, sr); // 192 and 256 bits may not be available
     SecretKey skey = kgen.generateKey();
     byte[] raw = skey.getEncoded();
*/
     byte[] raw = MD5Util.getMD5HashRaw(seed);
     return raw;
}

(NOTE: reason why i use the hash of the password is that code is compatible among platforms (client is Android device), while the commented version is NOT)

UPDATE#1

Short answer:

Presented logic is not even close to be considered a secure authentication mecanism (for Why? check Michael's answer bellow)

Decided to use Kerberos (AND not https, since I am not familiar + seems complicated to setup):

It is not a true version of Kerberos (like v4 or v5), it is just my own implementation so lets call it "similar with Kerberos" (I know, I know: DONT "roll your own encryption"!!!),

Here are some details:

  • it works on UDP (now)
  • authentication is done only once, by:

    • client sending a Authenticator message (contains: [userId] in plain text & [something_ecrypted] with [entered_user_password] (curently [something_ecrypted] contains just a timestamp, call it [authenticator_creation_timestamp])) NOTE: password is not transmited
    • server upon receiving message, tryies to decrypt the [something_ecrypted] with [actual_user_password] -> if SUCCESS then client is who it pretends to be, so i send him back a OK response (as in Kerberos this response contains some stuff, like a [public_key] (a RSA key, but encrypted with user_password) + ticket granting ticket (call it [TGT], encrypted with a password known only by server, currently it doenst expire, this [TGT] also contains some stuff, like these 2 timestamps: [TGT_creation_time_stamp] + [authenticator_creation_timestamp] (the one received in the Authenticator message))
    • after receiving this OK message, client has procured a valid [public_key].. so nice!
  • protection agains "reply attack" is not a 100% guarantee, but I see it "safe enought":

    • on each next HTTP reaquest, i attach as headers these 2 guys [new_request_creation_timestamp] (encrypted with [public_key], procured above) + the [TGT] (untouched, as received above)
    • on server I just need to validate [new_request_creation_timestamp] agains some math (obvious [TGT] needs to be valid too):

      ** i expect that the following variables to be almost equal

      delta1 = [TGT_creation_time_stamp] - [authenticator_creation_timestamp]

      delta2 = now()-[new_request_creation_timestamp]

      (I actually allow a difference between them of 5 seconds, but from my tests, its just a matter of some 10-20 millis,

      ** So initial delta (calculated when creating OK response to Authenticator) should perpetuate on next interactions.

I do find this new approach quite trust-worthy, but if you have an opinion or see a BUG in logic, please share.. Thanks

pulancheck1988
  • 2,024
  • 3
  • 28
  • 46
  • The problem with this scheme is that if the encrypted username can be used in place of the password, then it is basically the password. You're sending it over a non-encrypted, non-verified connection. You must use HTTPS for this scheme to work. See Michael's answer. – Marcus Adams Dec 02 '13 at 13:38
  • Don't use SecureRandom#setSeed() to derive a key. See http://stackoverflow.com/questions/13433529/android-4-2-broke-my-encrypt-decrypt-code-and-the-provided-solutions-dont-work/13438590#13438590 – kroot Dec 02 '13 at 18:49
  • [Don't roll your own crypto](http://security.stackexchange.com/a/2210/20774) – 1615903 Dec 03 '13 at 17:19

3 Answers3

3

Yes, this is a weak security mechanism.

  1. Anyone who captures the information sent to the server can easily replay it to authenticate themselves (replay attack).

  2. It is vulnerable to offline password guessing - anyone who captures the information sent to the server can then very quickly test a password list to find what password your user has chosen (by encrypting the observed username using the hash of each password in turn). The hashing can even be precomputed, speeding the attack up further.

Password based authentication protocols should be resistant to replay attacks and offline password guessing attacks.

Simply using an HTTPS (TLS) connection to your server and sending the username and password in plaintext would normally be a better solution.

In response to your update 1:

  • I strongly advise using HTTPS. It is used everywhere for a reason - it has undergone immense security review and been found to be (largely) secure - far better than what you can get through a SO post.
  • I haven't considered your updated scheme thoroughly, but as it is based on Kerberos it is also subject to offline password guessing attacks as I described above.
  • Having successfully authenticated, don't forget about then actually protecting your data - you'll likely need to derive a shared symmetric key then use authentication + encryption on your data...
Michael
  • 955
  • 4
  • 12
1

What i understand is : you are sending Username + Encrypted Username to the server.

Ans: Since you are sending the Username and the encrypted Username which is : UserName + AES(UserName + MD5 Hashed Password)

If anyone knows or find that you give the Username and also gets the Username from your data to server: No worries. There you stand with AES. If you have doubt in AES encryption check this. Your data is secure.

Community
  • 1
  • 1
Viswanath Lekshmanan
  • 9,945
  • 1
  • 40
  • 64
  • I am not a cryptography expert, but surely he should use SHA-256 (or another "more modern" algorithm) instead of MD5? – user253751 Dec 02 '13 at 10:24
  • see the last line of his question..,what he used that for is cross platform compatability – Viswanath Lekshmanan Dec 02 '13 at 10:26
  • 1
    what platform doesn't have SHA-256? – user253751 Dec 02 '13 at 10:30
  • Given the length of a MD5 hash, it would be fairly hard to brute force attack to reverse the encryption, however, given the known target value (Username), it could be fully automated. Once the unsalted hash was revealed, you could use any of many precomputed rainbow tables to reverse the MD5 hash. It's very vulnerable to a dictionary attack however. It also doesn't ensure proper authentication because the connection is not secure. See Michael's answer. – Marcus Adams Dec 02 '13 at 13:51
  • There are several known attacks on MD5. Collisions have been generated in 8 hours on a 1.6GHz Pentium. [http://cryptography.hyperlink.cz/md5/MD5_collisions.pdf]. If compatibility and speed are not constraints, there is no reason to use MD5 in a security-critical system. Other hash functions might not be an improvement (it probably doesn't matter because of the AES) but why would you knowingly use the worst choice? – user253751 Dec 04 '13 at 23:00
  • I'm no longer using initial proposed logic, since it turned out to be a week authentication mechanism.. but at some point i still use md5 to create a hashed_password, that i use for encrypting something (intention is just to encrypt with something that is not a word/ contains a word, like "377dbd7325c.." instead of "mikey2002" (so md5 or sha1 is the same to me)) – pulancheck1988 Dec 09 '13 at 15:33
1

I don't think this is a security flaw per se because even knowing both the plaintext message and the encrypted one, it is practically impossible to get the AES key. But I still wouldn't recommend to store the passwords hashed with MD5.

pupkinsen
  • 251
  • 2
  • 10