0

I'm trying to get a hobby/educational project off the ground that involves user accounts. Naturally, it will be critical for users to be able to log in securely. The information I will be storing and transporting for users is not intended to be personal or personally identifiable, but just on principle I'd like password transport to be as secure as possible.

I understand that the best way to get the user's password safely to the back end from the front is by using HTTPS. However, I don't want to pay for a CA for this learning/experiment project, and I also don't want to get browser warnings for self-signed certs, because though this is a hobby project, I would ultimately like to share it with the world (like a portfolio piece, something to share with friends, for people to actually find useful and fun).

Granted, you'd be right to say that if I want it to be a "portfolio piece," I should use best practices such as HTTPS, but I still don't want to pay an annual CA fee for what ultimately is a hobby/learning project.

I'm considering the asymmetric cryptography solution found here: https://github.com/travist/jsencrypt It's quite like the one suggested by ArthuruhtrA, and seems promising. It uses public/private key, so I could encrypt using public key on the front end, and transport encrypted to be decrypted on the back end with a secret/private key (where proper salting/hashing practices would occur before storage to a database). Does this seem reasonably safe, if untraditional?

Is there any other, better way to get user information (e.g. password) safely to the back end without browser warnings and without spending money needlessly?

Steverino
  • 2,099
  • 6
  • 26
  • 50
  • you could just host yourself inside Google Apps - or any other service that already has an SSL – David Brossard Aug 09 '16 at 03:59
  • I plan to host on AWS Free Tier to start, so I can learn something about AWS along the way. I know AWS provides CA services for free but I will have to research whether they provide that service on the Free Tier. Even if they do, would I have to go through the self-signed cert rigmarole in order to test locally before deploying to AWS? – Steverino Aug 09 '16 at 04:11
  • 1
    Possible duplicate of [Login without HTTPS, how to secure?](http://stackoverflow.com/questions/2336678/login-without-https-how-to-secure) – SilverlightFox Aug 09 '16 at 14:14
  • _"I still don't want to pay an annual CA fee"_ - you can get free certificate from some CA's, like https://letsencrypt.org/ – 1615903 Aug 10 '16 at 08:17

2 Answers2

3

If you use encrypted password from JavaScript it cannot be well secure since it is only client side customisation, i.e. it is not à service provided by the browser.

I would advise you to use TLS with a free certificate. You should have à look at letsencrypt.org.

Nicolas Henneaux
  • 11,507
  • 11
  • 57
  • 82
  • Can you elaborate? I don't understand why encryption would be less secure if performed by a JS library, than by the browser, if the JS library itself is trustworthy. Are JS libraries fundamentally untrustworthy? – Steverino Aug 09 '16 at 04:45
  • It can be changed by the user or a malicious plugin. The libraries themselves are no untrustworthy but when you send them to the client side it cannot be fully trusted. – Nicolas Henneaux Aug 09 '16 at 04:54
  • Couldn't malware intercept sensitive data before it even goes to transport, and send it to a third party? Heck, a user could have a keylogger installed unknowingly. If a user has an infected system, I'm not trying to protect them from that. – Steverino Aug 09 '16 at 05:00
  • ArthuruhtrA helped me understand what you mean. I see why you are right. I will look into Let's Encrypt and see if it can help me. – Steverino Aug 09 '16 at 05:10
  • @fls_acer : encryption is not less secure when done by js or browser, BUT the browser check if the certificate (containing the public key) used to encrypt is trusted by a Certificate authority. That JS lib doesn't. So you can't be sure that a man in the middle doesn't send HIS public key to the browser to read the answer. Just use https. HTTP can't be secure with your solution – Tom Aug 09 '16 at 12:32
0

I don't know what the best answer to this is. Obviously you've considered using a self-signed cert. I may be wrong, but depending on the OS and browser, you may be able to tell it to trust certs you have signed.

Another solution might be to use the asymmetric cryptography principle behind HTTPS, but without actually using SSL: Include your server's public key in your webpage. Use javascript to encrypt the data with it. Your server would then be able to decrypt it using its private key, without a middleman being able to do so.

Hope that helps! If I come up with something else I'll add it here.

Edit: On second thought, this solution would be super vulnerable to a man-in-the-middle attack. Sorry.

  • I like the asymmetric cryptography answer. I found a solution similar to this, which makes me happy. Is this as secure as HTTPS, if untraditional? – Steverino Aug 09 '16 at 04:13
  • Oh absolutely not. It'd be super easy to use a man-in-the-middle attack to intercept the connection and replace your key with his. Then he could read the data and re-encrypt it with yours so no one notices. You'd have to know the user had the proper key in advance, or they could verify with a CA, and that the JavaScript code wasn't tampered with. If using something like this, it would have to be an application which was not downloaded from the site, but pre-installed. On second thought, this is a terrible idea. Though still better than sending plaintext. – ArthuruhtrA Aug 09 '16 at 04:41
  • How could the man-in-the-middle read the data that was encrypted with the public key, if he doesn't have the private key from the server? If the private and public keys are both generated in advance in private on the server, and the public key is distributed with the client JS, a man-in-the-middle could intercept data but would be unable to do anything with (i.e. wouldn't be able to decrypt) it, right? I would still validate anything I decrypt on the back end to make sure I'm getting good input, but my goal is to protect user input (password) in transit. Wouldn't this accomplish that? – Steverino Aug 09 '16 at 04:50
  • 2
    What you say is true, but relies on the user getting the correct code and key in the first place. The man-in-the-middle would have to intercept the connection and swap your key out for his. Then he could decrypt it, because the client would use his key. So it would have to be a targeted attack, but it's still a hole I don't know how to avoid. – ArthuruhtrA Aug 09 '16 at 04:55
  • 2
    As Nicolas Henneaux pointed out, security should never be trusted to JavaScript. You have no control over it, anything could change that code or how it functions. – ArthuruhtrA Aug 09 '16 at 04:58