I would like secure access to the text output by three PHP scripts (the text output is JavaScript and html) . The security level is much less then financial data but important none-the-less. I have considered purchasing AND studying https and SSL certificates. Hostgator charges an extra $2/month for a private ip plus $50+ anually for a certificate. This is more then I want to spend for this project (time + money).

Is there a simpler solution that is:

  1. less expensive
  2. easier to implement.

I'm open to different approaches.

  • Does the solution need to (a) secure data that is in transit, (b) be secure against other users on the same shared server, (c) work for a variety of requesters from varying IP addresses?
    – danlefree
    Jun 23 '12 at 18:07
  • secure access to the text output by three PHP scripts --> SSL and a VPS (virtual private server) which usually means a personal IP address. I can help you get all of that for approximately 3 dollars monthly, plus a one-time SSL certificate (purchase one every few years). You don't need an SSL certificate to use encryption, though! You can create a self-signed one for free.
    – ionFish
    Jun 23 '12 at 19:19
  • @danlefree a) I would prefer it was secure in transit, and b) it is hosted on hostgator, other users on server is not top priority, c) I (the only user) should be able to access from any IP address
    – Roger
    Jun 23 '12 at 19:34

Given that you want the information to be secure (or as secure as is practical) in transit, you will want to encrypt the output of your PHP scripts using a password (or, preferably, a public key) stored on the server before returning the result and then decrypt the results locally with the password or private key.

A review of client-side libraries would suggest that jCryption could be used for this task with sufficient configuration, however, this variety of implementation is not documented at the jCryption site and implementation details would be more appropriate to StackOverflow.

  • Just remember not to hard-code the private key or shared passcode in the client-side script. Instead, use HTML5's File API to load the encryption key from a file (which you could keep on a personal USB drive). Jun 25 '12 at 7:57
  • Don't roll out your own crypto with JavaScript, read this: in particular, you won't be able to trust the integrity of the script and the cryptographic operation (in particular random number generation) aren't good enough.
    – Bruno
    Jun 26 '12 at 1:08
  • @Bruno Aren't good enough to what? Most people can expect to see their server or home machine as more likely exploit vectors than the JS crypto implementation on their website - and, where that's not the case, those to whom your statement applies already know who they are.
    – danlefree
    Jun 26 '12 at 4:56
  • @danlefree, if you want to use some crypto, you might as well do it right. Sometimes, a false sense of security can actually be worse than no protection at all. Here, access from an IP address implies that it may be done from non-trusted networks.
    – Bruno
    Jun 26 '12 at 9:35
  • 2
    I think we can agree that, if you want to do it right, you use SSL.
    – danlefree
    Jun 26 '12 at 11:14

If you want a secure access to your server, it is very difficult to do it without SSL. You could try to encrypt your data, but if someone is eavesdropping, he can do exactly the same as the browser would do, to decrypt the data.

There are hosters with good solutions for this though. The hoster i am using myself, offers a free SSL connection with an URL of the form http://[mydomain].[hosterdomain].ch . For $50 yearly, you get a certificate for your own domain, this without the need for a private ip address.

Technically it's also possible to create a certificate yourself, there are two problems with this approach. First you have to find a provider that allows to install such a certificate, and second your browser will give a warning and the user will have to accept this certificate manually.

  • 1
    That's not true. SSL is just a convenient way to use public key encryption and authenticate hosts. There's nothing magical about SSL that makes it the only way to do encryption over the web. If you weren't concerned with portability and public access, you could potentially implement the same type of public key encryption yourself without SSL, or even just use symmetric encryption with a shared key exchanged through a secure channel as danlefree suggests (which is very practical in this particular scenario). Jun 25 '12 at 7:52
  • 1
    @Lèse majesté - What you write is true, it is possible to do the encryption yourself. The problem is, that you have to install a software on the client side, before you can encrypt the data, while todays browser have built-in support for HTTPS/SSL. The software could even be a downloadable javascript, but then you face the problem, that an attacker can do the same steps as the client does. So, it is possible to do it on your own, but i can see only disadvantages. I will edit my answer anyway. Jun 25 '12 at 11:53
  • @Lèsemajesté, you should read this: matasano.com/articles/javascript-cryptography
    – Bruno
    Jun 26 '12 at 1:01
  • @Bruno: I have read that, but realistically it doesn't really change anything for 2 reasons: 1.) the same MITM attack could be carried out at the point of browser download; so there's no guarantee that crypto code in the browser is secure, as many browsers (Firefox and IE at the very least) aren't downloaded over HTTPS, and I'd wager that less than 1% of users actually bother to verify a download using file checksums (and many who do probably use MD5 or SHA-1). 2.) Using JS/HTML stored on a thumbdrive + CORS circumvents the JS code security problem. Jun 27 '12 at 4:24
  • 1
    @Lèse majesté - I shouldn't have written it so absolute, but actually my answer was meant to be positive. There are hosters, which offer what Roger wants for free, so why not use it? Jun 27 '12 at 7:00

Any custom code you write (or you) you do to display this output "securely" within the browser with SSL/TLS will be open to MITM attacks (see JavaScript cryptography considered harmful): browsers don't give you any way to verify the authenticity of the code you're running (going through all the JavaScript code whenever you use it is quite unrealistic).

You get a few options:

  • If you don't expect the output to be read from a browser, you can make your server encrypt the data, then you can save it from your browser and decipher that file using another application.

  • Some shared hosting services will still serve your content at https://www.yourserver.example/ using their own certificate (only valid for www.yourhost.example, but not www.yourserver.example).

    If this works in your case, and if you can trust that the certificate presented to you by the server is realistically that of the server on which your service is hosted (e.g. a cert that would be valid for www.yourhost.example), you can add a permanent security exception in Firefox (for example). This is usually not acceptable if your site is for more public use, but if you can judge that you can trust that server certificate, you will still have all the benefits of SSL/TLS when connecting to that server. This is clearly not ideal and require some of your own judgement when setting such exception. In your case, if the certificate you get for https://www.yourserver.example/is valid for secure1.hostgator.com (or something like that), it would seem reasonable to assume you're connecting to your shared server.

  • Use your host's shared SSL facility (as they seem to provide one). The URL won't look like it's yours, but it should at least be secure without any specific exception, and it's fine for personal access.

EDIT: To clarify the point about custom code.

Most modern browsers have a key/cert container (e.g. Software Security device on Firefox at least) where private keys can be used for SSL/TLS client authentication.

In this case, the private key is always controlled by the browser itself, and never given away to any page or script. However, browsers generally don't expose the private key in the same way for use by JavaScript so as to be able to decrypt some content without giving full access to the private key itself: in this case, you could never be certain that the key isn't sent to some other server, especially in a context where a MITM attacker would have been in a position to alter the script (which is unverifiable, since you can't really see the code you're running on a page).

There is a Mozilla JavaScript extension (signText) that should protect the key for signing the correct way, but there's nothing to decrypt. There are also on-going efforts to make more cryptographic operations available, but this isn't ready at this stage (it's not clear whether it will be implemented in IE either).

  • -1 "Any custom code ... will be open to MITM attacks" - this is incorrect in the case of a public key copied to the server and used in combination with a private key, used for Javascript-based decryption, which is never transmitted to the server.
    – danlefree
    Jun 26 '12 at 8:23
  • @ danelfree - The keypoint is, that you have to install something on each client manually, either a plugin, a certificate or a key. This maybe acceptable or not, that depends on the requirements of the user. It is not safe, to load the encryption-code from the server, because you cannot make sure that you get the original untampered code, without using SSL. Jun 26 '12 at 9:18
  • @danlefree, you can't access the private key in your browser from JavaScript and use it for signing. You'd need to write a plugin to do that. If you were to use a private key from a script (e.g. by pasting it in a form), it would effectively be accessible from the script. In a MITM scenario, the script could be altered and the private key could leave your browser quite easily.
    – Bruno
    Jun 26 '12 at 9:32
  • @Bruno If your server is merely spitting out ciphertext and you're running a local Javascript (sure, just save the key to a variable) to pull it down from the server and decrypt there is no MITM issue.
    – danlefree
    Jun 26 '12 at 11:06
  • @danlefree, no, a MITM could alter your script so as to make it send your private key wherever he wants. You can't realistically be expected to check the whole script (and everything that runs on that page) via the developer tools or similar whenever you go to your page. That's one of the key problems with script-based crypto. Even the jCryption author says it's vulnerable to MITM attacks (How secure is jCryption?)
    – Bruno
    Jun 26 '12 at 11:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.