Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticating a user over HTTP (instead of HTTPS)

INITIAL NOTE: This is just for a personal tinkering project; I'm not writing enterprise security here, and if I were, I'd know better than to try to write my own scheme. :-D

EDIT: To stress the above point, I tried to tag this under "iKnowThisWouldBeABadIdeaInRealLife", but SO wouldn't accept it because it was >25 chars. Just be aware that I KNOW it's not commercial grade!

I need a way to authenticate a user over HTTP (can't use HTTPS in this case). I need to know that the person on the other end really is who they say they are (to some reasonably high degree of confidence). Once I'm sure the user is legit, I do not care if the content between the client and the server are sent as plaintext.

The trouble I'm looking at is in trying to send a password from the client to the server without sending it as plaintext. I've thought about trying some public-key crypto in javascript, since some Google searching has turned up some fun-looking libraries.

Here's the scheme I'm thinking about:

(suppose A and A' represent the private and public keys, respectively; also, enc(text, key) and dec(cyphertext, key) represent the encryption/decryption functions)

    +------------------------+------------------------------+
    |         SERVER         |            CLIENT            |
    +------------------------+------------------------------+
(1) | t = randomToken()      |                              |
(2) | enc(t, A)           -------->  c                      |
(3) |                        |       A' = getKeyFromUser()  |
(4) | p                 <--------    p=dec(c, A')           |
(5) | if (t==p)              |                              |
    |     allowAccess()      |                              |
    | else                   |                              |
    |     denyAccess()       |                              |
    +------------------------+------------------------------+

One weakness I see in this is that the BAD GUY who was listening to the exchange, while he doesn't have A, now has a known ciphertext/plaintext combo, which I remember from crypto class is a BAD IDEA. I figure some salting could alleviate this somehow?

So here are my [two] questions:

  1. Is this a 'good' scheme? (remember that I don't CARE if anything following this initial exchange is plaintext - I'm ONLY trying to verify initial identity here)
  2. What would be the best way to get around the "known plaintext/cyphertext pair" weakness mentioned above? Salting?

Thanks!


EDIT: Thanks for all the discussion! Just to clarify:

  • I'm NOT worried about assuring the CLIENT that the SERVER is who they say they are. Only the opposite (assuring the SERVER the CLIENT is who they say they are)
  • I know about MITM attacks. This scheme is NOT intended to protect against them.
  • I know there exist plenty of solutions for this already. This is purely a learning exercise for me! I'm not trying to re-invent the wheel or build a better mousetrap. This is just for fun!
  • Here was my thought-process for the scheme: (I know I'm not quite using public vs. private keys properly, but bear with me for a sec)

    • Bob walks up to Alice and says, "Hey, I'm Bob."

    • Alice says, "Okay. I know Bob's 'private key'. If you're really Bob, take this secret message I just encrypted (with Bob's private key), and decrypt it for me."

    • Bob replies with the correct message, and Alice is happy.

like image 601
loneboat Avatar asked Aug 25 '10 19:08

loneboat


People also ask

Why would you use HTTP instead of HTTPS?

HTTP Isn't Secure on Private Networks While network security matters, so does transit encryption! If an attacker is able to gain access to any of your internal services all HTTP traffic will be intercepted and read, regardless of how 'secure' your network may be.

Is HTTP Basic Auth bad?

Using basic authentication for authenticating users is usually not recommended since sending the user credentials for every request would be considered bad practice. If HTTP Basic Auth is only used for a single request, it still requires the application to collect user credentials.


1 Answers

You could use HTTP Digest Authentication. That's already supported by most browsers, servers and various libraries.

EDIT:

If you really want to use some public key cryptography without SSL/TLS, you could have a look at HTTPsec

If you really want to invent your own authentication scheme, you should note that you got the encryption/decryption wrong with your labels (not sure if it's a typo, or maybe I'm not reading the diagram properly, it looks like you're doing enc(t,A) on the server side):

  • you encrypt using the public key
  • you decrypt using the private key
  • you sign using the private key
  • you verify the signature using the public key

In your scheme, you'd need the server to publish its public key and have the client encrypt its answer using that, to send it to the server, which would then be able to decrypt it with its private key. The difficulty then is to make sure that the public key is indeed that of the legitimate server and that it hasn't been intercepted and replaced by an attacker in the middle: that's where PKIs and certificates come into action with TLS (and HTTPS).

like image 103
Bruno Avatar answered Oct 08 '22 11:10

Bruno