Today I sniffed some unencrypted wlan traffic during class and I found quite a few passwords by a simple search for "pass" and "user" in wireshark. Turns out about half the sites we use for school don't encrypt their data in any way - they use GET-requests like ?username=user123&password=passwd123 on login. I started to think about this and now I wonder; what is the best way to avoid this? Encrypting would be easy to reverse, and one time keys could "easily" be captured as well. My best thought so far is to client side hash, but would this be a bad idea in some way?

UPDATE: I've obviously not told you the constraints here, but thanks for all the answers! The server does not have SSL and everything I use must be implemented in php/asp/asp.net server side or javascript on the client. The only preshared key there is is the password. Everything else will be known to the attacker.

I'm only trying to hide the password from the hacker. The rest of the information would be unencrypted, so a session steal would be possible. That will be the next problem. Maybe you could encrypt the information on the page with the nounce. Since there will be a lot of encrypted text a dictionary attack would be effective. This is why I don't want to use the user's password for encryption. Maybe I could use something like a 512/1024bit XOR key that I encrypt with the user's password? Or some part of the password, since a dictionary attack would still be possible - but harder.

Would a nounce encrypted with the clients say 2 first chars of his/her password be a good idea? A random number XOR'd with the passwords 2 first chars. This should be decryptable by the user, since he/she has the key (which would be taken from the entered password string through js). The nounce would be a random number, so nothing should be able to tell if it's been correctly decrypted.

Basically: 1. User types in username and posts/gets it to the server. 2. Server responds with a page with an encrypted nounce and a password box. 3. Javascript decrypts nounce, and password gets XOR'd with it. 4. Password is sent to the server, password gets decrypted and then hashed 5. Hash is compared to a stored one in the database.

Note: The server is free and it supports SSL, but I don't want to use it. I don't like SSL because it's broken.

  • 5
    "encrypting would be easy to reverse" - Not really.
    – k to the z
    Commented Nov 15, 2011 at 20:15
  • 1
    Define preshared key. For example, is a password considered a preshared key?
    – mikeazo
    Commented Nov 15, 2011 at 21:59
  • Thanks for the updates. A few more questions, what is your threat model? For example, are you worried about an active attacker (man-in-the-middle) or a passive attacker (eavesdropper)?
    – mikeazo
    Commented Nov 16, 2011 at 12:30
  • 2
    The PKI system is broken, SSL isn't broken. Whatever mess you just described as "secure" is beyond broken, its a joke. I mean this question is seriously embracing, you should not have posted a "solution".
    – rook
    Commented Dec 22, 2011 at 3:22
  • 2
    This question made me laugh. Especially the very last line. I very much do hope you meant it as a joke.
    – tylerl
    Commented Dec 23, 2011 at 5:36

9 Answers 9


You want the target server to be able to access the user name and password, and not the sniffer-powered attacker. So the target server must be able to do something that the attacker cannot. Since the attacker can buy the same kind of PC than the server, that extra power must be something that the server knows, but not the attacker.

Hey, there is such data: the password ! That's the point, isn't it ? It really is a pre-shared key between client and server.

Passwords are pretty lousy, as far as key go, because of the limitations of human brains. Still, one can work with that. The best protocols for that are Password Authenticated Key Exchange: they can escalate a shared low-entropy key (the password) into a shared high-entropy key, with which you can do all the yummy stuff of symmetric cryptography, which will keep (wire)sharks at bay. And PAKE protocols can do that while resisting offline dictionary attacks ("offline" is the important word here).

The bad news is that PAKE protocols, and, more generally, any authentication protocol which can be linked afterwards with exchanged data so that the authentication really resists active attacker, are difficult to get right. The simplest but still secure protocol turns out to be SSL with SRP (there is an RFC for that). The good news is that SSL+SRP provides password-based mutual authentication between client and server using no certificate whatsoever (and when people say that they do not want to use SSL, what they usually mean is that they do not want to dabble in X.509 certificates and the friggin' PKI market).

Unfortunately, SSL+SRP support is not widespread (GnuTLS is an opensource library which knows SRP).

  • I seem to remember when learning about SRP that it had some patent issues. I believe it possibly infringes on another patent (maybe EKE). Any idea if that is true? SRP is a good suggestion though.
    – mikeazo
    Commented Nov 16, 2011 at 0:15
  • PAKE is indeed a very nice mechanism. However, it may be overkill for this question: ordinary SSL is sufficient to solve the particular problem that Filip seems to be referring to.
    – D.W.
    Commented Nov 16, 2011 at 3:27
  • 1
    @D.W.: I was assuming (wrongly, it seems, as the OP detailed in his edit) that SSL was ruled out because of the certificate business -- that's the #1 reason why people do not like SSL. SRP shows that you can get SSL-with-password-authentication without any certificate.
    – Tom Leek
    Commented Nov 16, 2011 at 16:40
  • 1
    @Filip, SSL is not broken. Where did you get that impression from? (If you are talking about the BEAST attack, there are defenses/mitigations.)
    – D.W.
    Commented Nov 17, 2011 at 7:28
  • 1
    The "brokenness" of SSL is likely orders of magnitude less broken than anything you or any other non-cryptographer is likely to implement to accomplish similar goals. Commented Oct 22, 2012 at 14:29

if you use client side hash then it become actual site password and you didn't achieve anything.

  • 4
    It depends how you use client side hashing. If you use HMAC(nonce, HMAC(salt, password)) where salt doesn't change, and nonce change every time, then the "actual" site password is HMAC(salt, password). It means that the "actual" site password is stored in clear. But it also means that this site password is not reused by the user on any other site.
    – curiousguy
    Commented Nov 16, 2011 at 20:12

The best way is to use SSL. The mechanism exists for a reason. Alternative schemes tend to be either insecure or insanely complex.

You said you wanted to do it without using SSL, but you gave no reasons or rationale why. You didn't explain the situation you are in or what would justify avoiding SSL. Consequently, even if we wanted to provide you some alternate suggestions, it would be impossible to determine whether they meet your requirements.

  • 2
    The OP said the Server doesn't have SSL. If that is the only thing stopping him, he might as well pay an extra couple of bucks a month to add SSL support as that would be a better use of his time/money than implementing some hairbrained scheme (my answer included).
    – mikeazo
    Commented Nov 16, 2011 at 13:00
  • The server is free for me, and I don't like SSL. Commented Nov 16, 2011 at 20:08
  • 10
    "I don't like SSL" is not a valid basis for making a technical decision about what is the best way to protect yourself from a class of threats.
    – D.W.
    Commented Nov 17, 2011 at 7:08

If all you are interested in is authenticating the user to the server (and don't care about encrypting later data), Lamport's Hash would be easy to implement as there are already hash function libraries implemented in Javascript and PHP/ASP/ASP.net.

Lamport's Hash is a type of one-time password scheme that works as follows (Alice is the user, Bob is the server):

Initial Registration

Upon registration, Alice sends [n,hash^n(password)] to the server (where hash^n is the result of hashing the password, then hashing the result of that, then hashing the result of that, ..., n times). The server stores [n,hash^n(password)] in the database.


  1. Alice sends her ID (username) to Bob: "Alice"
  2. Bob responds with "n"
  3. Alice sends x=hash^{n-1}(password) to Bob
  4. Bob compares hash(x) with the digest stored in his database
    • If they match, authentication is successful and Bob replaces [n,hash^n(password)] with [n-1,x=hash^{n-1}(password)]
    • Otherwise, authentication fails and Bob retains what is in the database

Practical Considerations

  • You will most likely want to use a salt with the password (Bob can send the salt in #2)
  • Once n is small enough, Alice will have to change her password (or they can just change the salt), and she will have to re-send [n,hash^n(salt+password)] to Bob
  • Choose n large enough so that the reregistration isn't too often
  • Since this is only a one way authentiation (user is authenticated to server, but server not authenticated to user), man-in-the-middle is possible.

If Lamport's Hash doesn't meet your requirements (e.g. you need mutual authentication), SRP is probably your best bet, but by the time you have implemented it in Javascript and PHP/ASP/ASP.net, you could have rented a server which supports SSL which is clearly the best choice from the beginning.

  • 1
    Sound pretty good, but how would it be possible to defend against MitM fully? Commented Nov 16, 2011 at 20:16

The answer is TLS (not even SSL) without AES as the encryption algorithm, since there is a known issue with the combination of TLS, AES and WebSockets for example. Everything else (like encrypting the password in the client using javascript) is insecure. Of course, it cannot be read direcly using wireshark but the javascript may come from a man in the middle. so try to convince your school? to switch to TLS servers. This is the easiest way and it will not require any change of application code.

  • True story! Didn't think about the fact that the js is sent to the browser. I don't want to convince our school since the server is our (my) private playground atm. (nobody else uses it anymore) I don't have any big application to worry about either. Commented Nov 16, 2011 at 20:11
  • still, a school is kinda a closed system where - normally - the students have more IT knowledge than any teacher around. :-) so in case you really want to secure your password (or passwords), you should start in securing the communication using TLS, store your passwords on the server using PBKDF2 and so on. On the other hand, if you want to experiment a bit, try to implement SRP (just for the fun of it :-) ). I blogged about it a while ago: esskar.wordpress.com/2009/11/03/…
    – esskar
    Commented Nov 16, 2011 at 20:58

SSL cannot be as broken as clear text passwords. Use SSL. I think that Scheier has something to say about people who design their own cryptosystems.


I don't like SSL because it's broken.

That's a rather dramatic claim to throw out without any explanation nor supporting references. Do you mean all forms of SSL including TLS or specifically SSL v1-3?

It's a lot better than a lot of other attempted solutions to the problem.

The only way to establish secure communication is via encryption - and for a browser based client, if you're not using the builtin functionality of SSL, then you're delivering the code to implement the encryption (be it Javascript, activex, java, flash....) over an unsecured connection. Hence the code can be compromised. It doesn't matter if you use rot13 or a 4096 bit key with a PFS algorithm - if it's handled by code delivered insecurely then modifying the code to capture the password is easy.

If you think SSL is broken, then fix it - it's a much more profitable way to spend your time.

  • 1
    What he actually means is that the CA based PKI on which most SSL implementations rely is broken, which is a claim with some merit. But there is no way around it for a normal web-application. Commented Oct 22, 2012 at 22:16

If you can run JavaScript on the client, you could setup a Diffie-Hellman key exchange or a challenge / response mechanism based on the password's hash (don't store plaintext on your system!) and use that to do a fancy authentication process where an encrypted credential is returned for authentication.

Those won't stop active MITM attacks, but it will keep passive attackers from sniffing passwords.

  • 1
    This is insecure against Firesheep. Also, it is insecure against active attacks (as you correctly point out; but this is a severe enough problem to disqualify the solution). In contrast, simply using SSL does not have those problems.
    – D.W.
    Commented Nov 16, 2011 at 3:28
  • 1
    @D.W. Well, yes, if you want a secure connection then SSL is typically the way to go. The question specifically precludes that. Also, Firesheep can be mitigated through these methods with a rolling series of challenges that prevents replay attacks. SSL is better and simpler to implement since it's packaged, but if the asker is hell-bent on something, there are secure ways to exchange passwords in the clear with a passive listener.
    – Jeff Ferland
    Commented Nov 16, 2011 at 5:31
  • To make it even easier just have the server generate a random number challange, concat with the password, and hash using md5 (yes I know md5 is broken, use SHA if you care). As stated above this won't stop a MITM from modifying the javascript. If you instruct the users to view source all the time then you should be ok
    – user974896
    Commented Oct 22, 2012 at 18:59

First thing I'd check is if the server supports http authentication with digest authentication. You might be able to enable it via php.


It's not nearly as secure as SSL, but it could be a simple trick to keep people in your class from swiping your passwords. Use http auth to block the area of the site you need to protect. They'll see everything you're doing, but they won't get the http authentication password. (they will get any other password inside the session)

  • One problem with digest-auth is that it forces the server to store a badly hashed password. Commented Oct 22, 2012 at 20:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .