2

I'm using free hosting and I would like to know if there is a way to have a safe login system without a TLS certificate. All I do with this server is: POST HTTP Request with username and hashed password, then search for those values on server, and reply with "x" for yes and "y" for no. It's my first week working with databases and servers, this is why I'm not paying for a hosting service.

If the information is transmitted as hash to the server, and the answer from the server is NEVER the same (I mean, "x" is ALWAYS a different value and "y" is ALWAYS a different value), do I still need a TLS certificate?

The login is made on a desktop application and then is hashed and sent to the server.

There is no credit card info or any sensitive information, only username and password for MY application.

Please don't say "I don't know why you want to do it without TLS certificate because they are free" and such, I already talked with their support and they don't support TLS.

Luc
  • 31,973
  • 8
  • 71
  • 135
Lemon
  • 23
  • 2
  • If you control every User / App that uses your application you could go for application layer encryption with preshared secrets. But really that is no way to go for usability reasons. So yes, you can but I don't think you want that. – Ben Jan 08 '19 at 07:57
  • 3
    You're talking about transmitting the user's password in plaintext (in the POST request), which is far from safe. It's technically possible to get good security without SSL, but it basically involves re-inventing SSL. There are some similar previous questions [here](https://security.stackexchange.com/questions/41845/login-security-without-ssl) and [here](https://security.stackexchange.com/questions/73917/techniques-to-make-a-login-page-safe-without-using-ssl). – Gordon Davisson Jan 08 '19 at 08:04
  • 3
    Possible duplicate of [Login security without SSL](https://security.stackexchange.com/questions/41845/login-security-without-ssl) – Tobi Nary Jan 08 '19 at 10:03
  • 1
    I would say it is **not a duplicate** because the other question has a very specific scenario where the person trying to use the website has ssh access to the server. (I don't see how that is a realistic scenario, but whatever.) In this case, it's just securing HTTP without using HTTPS. I edited the other question to clarify. – Luc Jan 08 '19 at 10:54
  • Consider [Challenge-Handshake Authentication Protocol](https://en.wikipedia.org/wiki/Challenge-Handshake_Authentication_Protocol) (CHAP). The same password hash is never duplicated. *"CHAP requires that both the client and server know the plaintext of the secret, although it is never sent over the network."* Don't invent your own security, it is virtually never secure. – zaph Jan 08 '19 at 18:39
  • Obligatory: ["Schneier's Law"](https://www.schneier.com/blog/archives/2011/04/schneiers_law.html): "*Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can't break.*" – zaph Jan 08 '19 at 18:43

2 Answers2

5

If you control the client and server software completely, you can re-implement enough of TLS for security without bothering with public key infrastructure (PKI) - the certs and such - by hard-coding the trusted public key(s) into your client. This is a terrible idea, though; TLS is really, really hard to get right (witness the constant stream of bugs in libraries like OpenSSL) and contains a lot of stuff learned in decades of trying to perfect transport-level security (SSL 1 was so insecure it was never published, SSL 2 was found to be insecure pretty shortly after publishing, SSL 3 was found to be insecure a few years ago and is deprecated, TLS 1 - essentially SSL 3.1 - has in turn been deprecated by newer versions, etc.).

Trying to do authentication without TLS or something like it is not going to be secure. Technically there exists a protocol, Secure Remote Password, for authenticating securely over an untrusted network, but it doesn't support registration (you need to have some other secure way to tell the server the user's credentials) so it is probably unsuitable for this. There exist ways to be secure against a passive eavesdropper, such as HTTP Digest authentication, but an active man-in-the-middle - which is easier to get than you might think - can still compromise such schemes.

If your hosting provider genuinely won't permit HTTPS (and dear $DEITY what is wrong with them?), find a different one. For hobby projects or small-scale prototypes, there are tons of free providers. While you're at it, have a care for how you store and look up passwords; simple hashing (even with a salt) is insufficient, and beware of issues like SQL injection. Additionally, if the server and client exchange any information other than the login request and response, make sure the other endpoints have adequate security (HTTPS or similar, but also proper authorization checks, no XML attacks, deserialization attacks, etc.; web services are easier to secure than web sites, but there's still a ton that can go wrong).

CBHacking
  • 40,303
  • 3
  • 74
  • 98
  • wow, that's a complete answer. Thank you, i moved to GearHost now and i'm still learning about domains and how to add a certificate for it. Btw, about how to safely store passwords, SQL injections, XML attacks, etc. do you have any advice or any page that you recommend? because there is A LOT of information about this on the internet and that's a little confusing for someone like me, because a lot of pages differ. – Lemon Jan 08 '19 at 10:08
  • @Lemon to answer your comment: you should refer to the OWASP project first. Then wikipedia is a rather good source because it is proof-readed (it might not be the best or most complete, but it is generally a good introduction to topics). Then search here, on this website, because your questions will most of the time have been already answered. Do no hesitate to ask if you do not find an answer. – A. Hersean Jan 08 '19 at 15:49
-1

CBHacking's answer is correct: just use TLS.

That said, hashing the password before sending, as you described, is a good step. This has saved my neck before when someone in school thought they were cool, did a passive intercept, and deleted half of a forum that I was an admin on (I was 17 and the free forum host did not offer HTTPS). The attackers got stuck when they didn't have the admin password to enter the admin panel (a million kudos to SMF Forums for implementing the hashing and extra password check).

Now consider this: you send the password hashed, but an attacker can observe the hash being sent. They do not know the original password, but they can replay the request. They can just send whatever you sent, and the server will accept it.

So another step is to make this a challenge-response system. This is what a lot of protocols use, for example NFC: the card (also known as 'tag') will generate a challenge and the reader has to respond correctly before being allowed to read the tag. This can be a secure authentication system.

You should also use slow hashing, such as Scrypt or Argon2 if possible. See: How to securely hash passwords? This makes it harder for an attacker to attack your password hash.

Next, you should encrypt and sign the traffic: it's great that you can authenticate securely, but an attacker can still modify the commands you are sending and see the data you are transmitting. Something like AES-GCM does both, or if you want to do it with more traditional methods, AES-CTR with HMAC is a common choice. You could use the solution to the challenge-response system as password, and instead of submitting the response, you encrypt the text "correctpassword" (or something like that) and send that to the server. If the server can decrypt it correctly, it knows that you had the right password.

Finally, an attacker can still do a replay attack: you have a good login, you have encrypted requests, you sign the requests... but what if an attacker just replays a random request? The server does not know that it is invalid. Therefore, you should include a sequence number on both sides (from the client to the server and vice versa).

You know what you just did? You just re-implemented a large part of TLS, basically the part after the key exchange. Now think of the history of vulnerabilities that TLS has had, which is huge, despite having experts working on it. It is fun to thinker with this sort of thing, but please do not use it for anything that matters! I'm just answering the question because it's interesting stuff, at least to me, not because I think you should actually use this in production! :)

Luc
  • 31,973
  • 8
  • 71
  • 135
  • 1
    Hashing the password before sending is **not** a good step, it just makes the hash the password. – zaph Jan 08 '19 at 18:37
  • @zaph I beg to differ: the main purpose of hashing passwords is to prevent those who obtained the database (or in this case, the transmission) from learning the original password. That you can't do pass-the-hash in web applications is a nice side-effect, but that is not the main purpose. See, for example, this question: https://security.stackexchange.com/questions/36833/why-should-i-hash-passwords – Luc Jan 08 '19 at 22:07
  • 1
    idk why people down voted you, that was a good answer as well. Thank you for taking time to write it, it helped me understand a lot of things. – Lemon Jan 08 '19 at 22:10
  • 1
    The answer is very good except for hashing the password on the client. Don't let the client control the quality of the hash. As stated in the second full paragraph of the answer sending the hash is a potential vulnerability. An attacker could modify the client hash method. – zaph Jan 09 '19 at 02:42
  • @zaph Wut? Client-side hashing is a good thing, not bad! Since the argumentation goes way beyond the scope of a comment section, I wrote an answer here: https://security.stackexchange.com/a/201099/10863. I'm interested to hear your thoughts on it. Feel free to [start a chat](https://chat.stackexchange.com/users/44361/luc) or @ mention me in [the DMZ](https://chat.stackexchange.com/rooms/151/the-dmz). – Luc Jan 09 '19 at 10:34