On Jun 25, 4:33 pm, peterk <
peter.ke...@gmail.com> wrote:
> Your second option, if for example your running an API-service, might
> be HTTP Digest authentication... I haven't tried it yet. I know HTTP
> Basic works for sure though. But if Digest works also, you could use
> that to secure API calls whilst also protecting your user's passwords.
I've found HTTP Digest to be unreliable -- there seems to be some
ambiguity in the spec, and some browsers/servers implement it slightly
differently. This tends to manifest itself as your browser randomly
'forgetting' your credentials and asking you to log in again (in
reality, the server has just spontaneously decided your login is
invalid and demanded fresh ones).
HTTP Basic over SSL is simpler and works on everything -- if you have
SSL, of course.
> Finally, with form-based logins there still might be the potential to
> roll your own encryption if you don't want to send that information in
> the clear, as I mentioned in my previous post. Again, though, I have
> not implemented this myself and I'm not entirely sure how feasible it
> is..but it would probably be more secure again vs HTTP Digest. If
> anyone has any comments on whether that'd be worth one's while or not,
> I'd be interested to hear.
Well, it depends on how paranoid you are. :)
One problem is that the browser has to get the javascript encryption
code from somewhere. Without SSL, you can't guarantee the security of
that code itself! It could do anything...
It does, at least, raise the level of attack required from passive
(monitor communications only) to active (intercept/modify/inject
traffic). This might be enough to put attackers off -- but if you
were, for example, using a public WiFi access point, it's quite
feasible for the AP owner to modify traffic as it passes through (eg
http://www.ex-parrot.com/~pete/upside-down-ternet.html ). Like I say,
it all depends on how paranoid you are, and whether anyone can
actually get benefit from hacking your app.
Plus, as always, there's the issue of distributing/exchanging keys.
I'm working on an application that has two ways to access it: via
regular web-browser, and via a desktop app.
The desktop app is the reason I can't use Google accounts for my app.
I'm not comfortable with (and nor is it good practice) asking users to
enter their Google account details into my desktop app, especially
when you consider how many different things that password unlocks
these days.
(I really encourage other people not to do this either -- it would
just be creating a long-term phishing disaster.)
So, I've put together a simple 'secure session' system that does no
encryption, but it _does_ sign every packet for authenticity, and uses
that instead of logging-in the traditional way. The sessions don't
contain sensitive data, I just want to prevent Bad Guys(tm) from
accessing the service without an account, or trashing someone else's
account.
So instead of saying, "Hi, I'm user Canis password Seekrit" and, then,
once logged in, saying "I want to modify some data now", the client
would simply say, "Hi, Canis wants to modify some data pls kthxbye.
<signature>" where <signature> is a sha1 hash of (Canis, Seekrit,
modify-some-data, sequence number).
The sequence number is to avoid replay attacks -- you can skip
sequences (to account for dropped connections) but you can never go
back. The server verifies all this stuff at the other end.
(I actually go a bit further than this to avoid chosen-plaintext/
forced-hash-collision dubiousness, but that's the gist of it. I
probably shouldn't worry so much, but what can I say? I read a lot of
Schneier when I was young... :P )
It works pretty well, but there are two problems at the moment:
1. Currently, there isn't really a secure way to _set up_ an account.
The server needs to know the correct password somehow. You can do it
from home, though, over your hopefully-more-secure personal
connection, then know that you're 'safe' when out-and-about on WiFi,
which is an improvement.
2. There's no graceful way to integrate this with the non-desktop
version -- how does a user log into the web app securely?
Now, we can solve 1. by using Real Crypto(tm) -- the server has a
private key, the public key is embedded into the desktop app (which is
distributed securely), and then we're ready to rock.
(This _could_ replace the whole digest system I described above, but
applying public-key crypto to every request is going to incur
significant overhead. You can encrypt a session key of course, but
really, we're getting into "re-implementing SSL from scratch"
territory here, which we're bound to do worse -- slower and less
securely -- than real SSL. I don't recommend it).
The catch is that all the crypto libraries I can find for Python are C
extension modules, so we'd need to persuade Google to add one for us.
This seems like a useful thing for them to support, though, and
probably requires less infrastructure-hackery on their part, to get a
useful end result, compared to SSL.
Failing that, recommendations for a good, pure-Python asymmetric
crypto library are welcome :)
Now, how to solve problem number 2? Maybe serve the javascript off a
non-Google, SSL-secured site, that does that and nothing more? With a
nice long cache time, this should be pretty cheap if you shoved it in
an S3 bucket. This is my current plan, but I'd love a better one. It's
still a slow/gronky method though, if you ask me. Sucks for anyone non-
JS-enabled too.
This also points out another approach to the creating-new-accounts
problem: The client SSL's to an offsite server, which already has
credentials with the AppEngine site. The SSL server doesn't need to be
massively scalable -- although it's a choke-point, it's only on new
account creations, it should only ever get one request _ever_ per user
of your system.
Anyway, enough of me thinking out loud. Hope some of that's of use.
-c