4

Is that worth it to use some JS encryption library to make safe communication instead of SSL? I ask this because I want to secure my application built on Google App Engine and it doesn't let you to use your own domain for SSL requests. What are good ways to communicate securely with GAE? Thanks.

Sergei Basharov
  • 51,276
  • 73
  • 200
  • 335
  • 3
    I would have to say No. JS encryption != SSL. Not by a long shot. – Loktar Feb 28 '11 at 17:12
  • SSL gives you lots of nice things like non-reputation (the client can trust you are who you say you are), and protection of man-in-the-middle attacks. JS cypto library isn't a great idea when SSL does so much more for you. – russau Mar 01 '11 at 02:21
  • @russau: although precisely because of the "can't use your own domain for HTTPS" thing, GAE doesn't let the client trust that you are who you say you are. It lets the client trust that you're Google (i.e. that they're talking to Google), because it's Google's name on the certificate. They may also believe that Google is acting on behalf of who you say you are, but if so it's not because SSL has proved it. – Steve Jessop Mar 09 '11 at 01:30

4 Answers4

4

[Note: See Correction below]

It is possible to securely communicate with an authenticated server on google app engine with a custom domain, but it is a hassle. As some of the other answers indicate, you must be very careful how you implement the encryption to prevent man-in-the-middle attacks.

Here are the basic instructions for python, but you could could modify for java. Expect to spend at least a day or two getting something like this up and running.

Prerequisites:

  • A python RSA and AES library for the server. pyCrypto works well on GAE.
  • A javascript RSA and AES library to be run on the client. I used stanford's RSA library and crypto-js for AES. I can't remember why I didn't just use one library.

Instructions:

  • Step 1: Offline, create a RSA public and private key pair. Here are pyCrypto instructions.

  • Step 2: Save the generated RSA public & private keys in a python file, be sure the private key is not publicly accessible.

  • Step 3: On the server, create a request that generates a javascript file. The javascript file should only transmits the public key to the client. For example, it would only return a file with this:

    var public_key="[your public rsa key here]"

  • Step 4: In your app.yaml file, make sure that the generated javascript file is only served over SSL (i.e. set secure: always). See instructions here.

  • Step 5: On the client, load the javascript file using ssl. However, instead of using your custom domain, use the appspot domain. For example, add this to your html file:

<script src="https://example.appspot.com/publicKey.js"></script>

The client will now have an authenticated RSA public key preventing man-in-the-middle attacks. Note: accessing other domains is normally prohibited by browsers to prevent XSS, but there is a loophole which allows you to load javascript files.

  • Step 6: On the client, generate a random private key. Use a javascript RSA library and the public key we got in step 4 to encrypt the random private key. Send the encrypted private key to the server.

  • Step 7: On the server, decrypt the random key generated on the client using the RSA private key.

    At this point, both the server and the client have the same private key. Even better, because the original public key was transmitted over SSL, we can authenticate that the server is really who we believe it is (i.e. no man-in-the-middle).

  • Step 8: Now the server and client can encrypt and decrypt any data they want using the randomly generated private key and their respective AES libraries.

-- EDIT: CORRECTION --

Bruno's comment below is 100% correct, the above steps are insecure. Although the steps above do work to setup an authenticated session between client and server, the only way that the user would really know it was authenticated is if they checked the code to ensure that the public key was being loaded using https. A man-in-the-middle could serve the initial html page modify the <script src="https://... code to point to something else.

Instead, take a look at wwwizer.com.

speedplane
  • 15,673
  • 16
  • 86
  • 138
  • 3
    There's little point using JavaScript encryption at all, since the client can never really be sure what it gets really comes from the server (unless you're using HTTPS as well, but that makes the JS crypto redundant). – Bruno Mar 29 '12 at 18:05
  • The above steps do authenticate because they use SSL for public key distribution. So they can be sure the public key is actually coming from the right server. Yes, there is a bit of redundancy here. You could probably have the server generate the private key and transmit it over SSL in a javascript file and thus would not need to deal with RSA. However, that would open up other problems. You would not be able to change the private key without reloading a page. – speedplane Mar 29 '12 at 18:54
  • You can't seriously expect users to check the source code of the page or use the developer tools to verify it's using an `src="https://..."` URI correctly: as a user, you don't really know what you get, or where you get it from (there is a point in being able to see the blue/green bar in the browser). In addition, [JavaScript crypto has other shortcomings](http://www.matasano.com/articles/javascript-cryptography/). Don't try to mimic SSL/TLS over HTTP with JavaScript: use SSL/TLS as directly supported by the browser. – Bruno Mar 29 '12 at 19:03
  • I thought about it for a bit, you are 100% right. The above steps are not secure if someone is modifies the original html file containing the script tag. Thanks. – speedplane Mar 29 '12 at 22:34
  • 1
    Although this wasted a great deal of time, it was a highly educational experience on how to get secure communication wrong. Thanks for pointing it out. – speedplane Mar 31 '12 at 01:21
3

Javascript is a client side language, meaning it runs in the user's browser, so any user can alter, manipulate and disable it as they please; rendering your encryption useless.

EDIT: Don't you mean Java?

HyderA
  • 20,651
  • 42
  • 112
  • 180
  • So, the more important question, actually, is how to make connection between client and my GAE app secure on my own domain, not on appspot.com and using JS library was one of ideas. So, I suppose I should better to realize how to deal with that appspot restriction than using JS encryption library. Thanks. – Sergei Basharov Feb 28 '11 at 17:18
  • http://googleappengine.blogspot.com/2008/10/announcing-https-support-for-appspotcom.html – HyderA Feb 28 '11 at 17:20
  • 2
    Any user can alter, manipulate and disable their end of an SSL connection, too. Javascript is useless here, but not because the _user_ can modify it. – Nick Johnson Mar 01 '11 at 02:09
  • Good point Nick, enabling security is a user choice, it's for their own benefit. And JS is bad choice because it could be disabled for other reasons, ironically, it's usually disabled for security reasons. – HyderA Mar 01 '11 at 04:44
2

No, it's not worth it, because you have to send the Javascript code to the client somehow. The attacker could simply modify the Javascript to make it possible for him to read (or modify) all the communications, rendering all your protections useless. SSL really is the only option.

Nick Johnson
  • 100,655
  • 16
  • 128
  • 198
0

You have to use https, but you can't use it on your own domain with appengine. They say that they will add that ability soon, though. We've been using the annoying https appspot domain assuming that they really will add support for https custom domains, but in the meantime none of our (~75) customers have complained about the appspot thing.

I guess the real question is how many people AREN'T customers because of the appspot thing... but I suspect it's a small number.

Riley Lark
  • 20,660
  • 15
  • 80
  • 128
  • How to better architect my app to deal with https on appspot.com then? How should I organize it? Thanks. – Sergei Basharov Feb 28 '11 at 17:55
  • @Sergey you don't have to change the architecture of your site at all. You can restrict certain paths to "secure only" so they can't be accessed via http. Also, be aware that any cookies you're setting on yourdomain.com won't be visible on yourdomain.appspot.com. – Calvin Feb 28 '11 at 18:33
  • I am building my app with heavy use of AJAX/JSON where almost all elements in the interface are built using AJAX requests. How do I deal with this? Thanks. – Sergei Basharov Feb 28 '11 at 20:04
  • The AJAX requests will automatically go over https if the host page is sent over https. You don't need to worry about it. – Riley Lark Feb 28 '11 at 20:29