views:

66

answers:

2

I need the username/password to be scrambled at the client-side before sending it over via HTTP GET/POST. And the server will decode it with Tcl, before the checks against database.

Currently I'm thinking about using JavaScript for the client-side. Java Applet will also do.

Is there any way, that I can easily achieve it, using Simple XOR or any other methods? (Examples would be much appreciated)

I've found the few samples in C/Python/.NET/Java... But not in JavaScript and Tcl.

SSL is not an option to use, sadly.

+1  A: 

If ssl is not an option, then I suggest the following scheme, which many sites use instead of SSL:

  1. On the client side, combine the user name and password, then calculate a hash from it (MD5 is a popular choice).
  2. Send the user's name and hash over to the server
  3. On the server side, retrieve the password for that user from the database.
  4. From the user name and password, calculate the hash and compare it with the client's hash. If the two match, then the passwords match.
  5. For added security, add a little random text to the user+password mix. This random text, AKA the "salt", must be known on both the client and server sides.

Here is a suggestion on how to calculate the hash using MD5:

package require md5

proc calculateHash {user password salt} {
    return md5:md5 -hex "$user:$salt:$password"
}

How to use it:

set user "johnny"
set password "begood2mama"
set salt "myDog_is_meaner_than_yourDog"

set hash [calculateHash $user $password $salt]
Hai Vu
Just to clarify: you do you mean for the salt value to be generated randomly by the server for every logon attempt and passed to the client (probably as part of the page data). This means you get a different MD5 hash for every logon even with the same username and password.
Jackson
The application needs to pass username/password to database, in original form. Is there a way to un-salt it, once the script receives the salted data?
superNobody
Or can you help me to translate this C/C++ to Tcl? I think that will do okay. [http://osix.net/modules/article/?id=96]for(int i = 0, y = 0; i <= strlen(data); ) { for(int o = 0; o <= BLOCK_SIZE; o++) { if(data[i] != '') { data[i] ^= key[y]; } i++; } y++; if(key[y] == '') { y = 0; } }
superNobody
@superNobody: To do that you first decide what encoding to work with (and use `encoding convertto` to transform to the byte sequence) then use `binary scan` to convert the binary string to a list of values. That done, you're iterating over the values, applying the xor, and then converting back to bytes with `binary format`. If you want this expanded, ask as a proper question!
Donal Fellows
@HaiVu: I'll vote for you if you give the client-side JavaScript ;)
Gra
@Jackson: The salt value is agreed upon between the server and *all* clients. The reason: many attackers has a dictionary of commonly used passwords and their MD5 hash. They can use that to carry a brute-force attack. By adding salt, you lessen the risk as such dictionary will be used less. For this reason, the salt value is not a secret: anyone who write a client to log in will need to know it.
Hai Vu
@superNobody: No, the hash function is one way: it is nearly impossible to take an MD5 hash and get back the user/password/salt combo. That's what hash functions do: they perform a one-way transformation.
Hai Vu
@gra: I appreciate your intention to vote for my answer. If you google for javascript and md5, you will find plenty of answers.
Hai Vu
@Hai Vu: I think you have missed my point; if the salt value is the same every time then the hash value produced will be the same every time. So if an attacker can monitor the network traffic they may be able to gain access by replaying the response without ever knowing the actual password.
Jackson
@Jackson: I got it now. That's the problem of not using SSL.
Hai Vu
+1  A: 

superNobody,

You should consider alternatives to storing plain-text passwords in the database. See:

Instead of encoding the password in Javascript, then decoding the password in Tcl to compare with the database, you should consider SHA1 hashing in Javascript, and storing SHA1 hashed values in the database.

There are several available examples of a SHA1 hash function in javascript (just Google 'sha1 javascript'). The tcllib Tcl library has SHA1 support.

As HaiVu mentioned, you should also consider hashing / storing more than just a straight password hash, but instead use something like SHA1( username + websitename + password ). You can calculate this on the client in Javascript, and store it in the db.

bsterne
+1. Never store plain text passwords. Also, don't reinvent the wheel, especially with Cryto and security.
RBerteig