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