7

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.

Tom Leek
  • 170,038
  • 29
  • 342
  • 480
Filip Haglund
  • 1,593
  • 1
  • 11
  • 20
  • 5
    "encrypting would be easy to reverse" - Not really. – k to the z Nov 15 '11 at 20:15
  • 1
    Define preshared key. For example, is a password considered a preshared key? – mikeazo Nov 15 '11 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 Nov 16 '11 at 12:30
  • *"The server does not have SSL"* - So why don't you turn on SSL? That's going to be **vastly** easier than designing and implementing your own replacement (and if you design your own replacement, it'll probably have security problems as well, as you are starting to discover). – D.W. Nov 16 '11 at 17:13
  • I do not own the server, and it's just for fun right now. Threat model contains everything imaginable. Of course it will have problems. Let's find them! – Filip Haglund Nov 16 '11 at 20:06
  • 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 Dec 22 '11 at 03:22
  • 2
    This question made me laugh. Especially the very last line. I very much do hope you meant it as a joke. – tylerl Dec 23 '11 at 05:36
  • OK... SSL/TLS is the most secure version of public key cryptography to date... and is definitely not broken. – KnightOfNi Jan 28 '14 at 23:31
  • For web applications any alternative is *far* more broken than SSL. You can get around SSL for client applications, but not for web applications where the javascript needs to be sent securely to the client. – CodesInChaos Jan 30 '14 at 18:09

9 Answers9

13

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).

Tom Leek
  • 170,038
  • 29
  • 342
  • 480
  • 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 Nov 16 '11 at 00: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. Nov 16 '11 at 03:27
  • @mikeazo: there's discussion about the initial EKE patent by Bellovin and Merritt (from 1992, so it should soon expire anyway) and a possible Lucent patent filed in 2001. I do not think it has been conclusively settled one way or another. – Tom Leek Nov 16 '11 at 16:38
  • 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 Nov 16 '11 at 16:40
  • I don't like SSL - it's broken, and I don't own the server so i can't turn it on anyway. – Filip Haglund Nov 16 '11 at 20:07
  • 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](http://security.stackexchange.com/questions/7416/what-can-i-do-about-tls-1-0-javascript-injection-vulnerability-on-my-server).) – D.W. Nov 17 '11 at 07:28
  • It's broken because authorities give out certs to 192.168.x.x, and multiple certs to google.com for example. The cert authorities broke SSL. – Filip Haglund Nov 18 '11 at 20:24
  • 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. – Stephen Touset Oct 22 '12 at 14:29
7

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

AaronS
  • 2,575
  • 5
  • 22
  • 26
  • 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 Nov 16 '11 at 20:12
7

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.

D.W.
  • 98,860
  • 33
  • 271
  • 588
  • 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 Nov 16 '11 at 13:00
  • The server is free for me, and I don't like SSL. – Filip Haglund Nov 16 '11 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. Nov 17 '11 at 07:08
3

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.

Authentication

  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.

mikeazo
  • 2,827
  • 13
  • 29
2

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.

esskar
  • 639
  • 1
  • 5
  • 12
  • 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. – Filip Haglund Nov 16 '11 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: http://esskar.wordpress.com/2009/11/03/secure-remote-password-protocol-srp/ – esskar Nov 16 '11 at 20:58
1

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.

MCW
  • 2,572
  • 2
  • 16
  • 26
1

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.

symcbean
  • 18,418
  • 40
  • 74
  • 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. – CodesInChaos Oct 22 '12 at 22:16
1

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.

Bruno Rohée
  • 5,351
  • 28
  • 39
Jeff Ferland
  • 38,170
  • 9
  • 94
  • 172
  • 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. Nov 16 '11 at 03: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 Nov 16 '11 at 05: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 Oct 22 '12 at 18:59
0

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

http://www.php.net/manual/en/features.http-auth.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)

mgjk
  • 7,545
  • 2
  • 21
  • 34