I have a question/idea: as we gained a lot of control of the client
(with GWT) wouldn't it be an advantage to calculate the bcrypt hash on
the client side? This would offer some protection against password
sniffing if the login is not done over SSL.
I had a quick look in the Java bcrypt source and it only depends on
java.security.SecureRandom to provide randomness calculating the salt.
Any comments welcome.
- Martin
P.S: I hope this is the right forum to talk about the Incubator
1. transporting a hash algo to the client doesn't help a whole lot, as
the attacker can just modify this code in transit. It does stump Eve
(Eve = cryptospeak for a hacker that can only eavesdrop, not modify
anything), but Mallory (= cryptospeak for a hacker that can change the
flow of data or redirect connections) won't be stymied.
2. You CANNOT use jBCrypt in GWT. GWT plays fast and loose with
numbers (they're all doubles), which means they don't overflow
correctly. jBCrypt depends on these overflows. You need an explicit
implementation of BCrypt for javascript, written from the ground up
with js in mind, and it will probably be many factors slower than
server-side implementations. BCrypt is already slow-by-design. Could
be that it's too slow for client side use.
3. Assuming we do have a hash algo on the client, you can do something
pretty neat though: login over HTTPS, share secrets and store in
cookie. Then redirect to HTTP (this doesn't cause warnings), read
cookie (cookie is used only as communications mechanism between the
HTTPS and HTTP side of things), *DELETE* cookie, and start generating
one-time tokens as authenticators for every request. Server keeps
track of these and thus replay attacks are eliminated. Mallory can
still screw you over by injecting code that retrieves the Cookie and
form-sends it to his server (or, as it's Mallory, anywhere so he can
sniff it). With this info Mallory can now also generate new tokens as
well.
The amount of effort involved to go above and beyond like this is
extremely significant, and as you can see, Mallory can break
everything anyway. Still, not sending a password plaintext certainly
has value. However, I still haven't found a decent js implementation
of a hashing algorithm. Also, if Mallory needs to be stopped, you
*NEED* to run the whole site over certed HTTPS, and make sure your
users understand that HTTPS is meaningless without also looking at the
URL address bar and confirming that they are on the right server.
On Oct 2, 3:19 pm, Martin Portmann <martin.portm...@gmail.com> wrote:
> I am referring to this document:http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecur...
>From the client side using SSL is probably the best way to protect the
password from going to the server without being sniffed.
My current plan is to use the SHA-256 implementation at the client
side (GWT with JSNI) and a bcrypt password hash on the server side.
The code would even have a fallback mode for non-JavaScript clients
that will simply use a basic HTML form and transmits username/password
in the clear (calculating the SHA-256 hash on the server side).
This would would defeat Eve on the wire and still offer all the
protection against dictionary attacks on the server (assuming the
password hashes can be retrieved). This would allow quite secure login
over a normal HTTP link without the need for a SSL vertificate (with
the associated price) and the need of a dedicated IP.
I am really not too worried about Mallory - once in that position you
can take over the whole client machine.
Any comments on this?
- Martin
> > P.S: I hope this is the right forum to talk about the Incubator- Hide quoted text -
>
> - Show quoted text -
However, mallory is pretty rare, and there is no way, *period*, to
protect against mallory without SSL. Thus, if SSL is not an option,
Mallory is no longer a concern from an implementation viewpoint: He's
already in.
So, just so I get this right:
You want to have, in the database, per user:
1. SHA256 salt
2. bcrypt salt
3. result of BCRYPT_HASH(bcryptSalt, SHA256_HASH(sha256Salt,
password))
Where the bcrypt salt is never transmitted off server (no point), and
the sha256Salt is given to anyone who asks regardless of credentials.
It's a bit complicated but it sounds reasonable and the extra step of
sha256 hashing on the client adds significant security benefit.
To be specific about these benefits:
1. Eve can no longer see Alice's password (Alice is standard user).
Hiding this is a good thing as users tend to re-use the same password
on different sites.
2. Eve can *still* see the sessionID and can thus use a replay attack
to impersonate Alice. This is difficult to solve*.
3. Eve can *still* see the data that Alice and your server are sharing
with each other. e.g. if this was an email app, Eve can see the
emails, both outgoing and incoming. This similarly difficult to
solve**.
*) You can solve sessionID replay attacks by some more hashing: We
begin by introducing a third salt, the authSalt. This salt is returned
upon successfull authentication, along with the sessionID. The client
(who knows the password) will now calculate sessionBase =
SHA256_HASH(authSalt, password). The server also knows the value of
sessionBase (so the server needs to store sessionIDsalt AND
sessionBase in the database!). The client, on every request, performs
the following operation:
key = sessionID + " " + counter + " " + SHA256_HASH(sessionBase,
counter++);
and sends this key along with every request. The server can split this
string, then know which session we're in (using the sessionID), and
also verify that this is the client and not Eve doing a replay attack,
because we have sessionBase, and we get the counter in the message as
plain text, so we can also calculate SHA256_HASH(sessionBase, counter+
+). But eve can't, because sessionBase has never been shared. The
server MUST store, for each session, the last seen counter, and any
messages with a counter equal to or lower than the last seen counter
for that session is not a valid request (as eve could be replaying).
However, this scheme is still vulnerable to the original password
transfer: If Eve is around when the user signs up or changes password,
you're in trouble, and no amount of hashing will help. You could use
public/private keypairs, but that's many orders of magnitude more
difficult so I fear for implementation speeds in javascript. It's also
very complicated.
Contrast this to the simpler scheme without this addendum, and in
theory at least your client could supply only the
SHA256_HASH(serverGeneratedSalt, password) to the server. While
certainly not as good as the bcrypted hash, it's still an excellent
barrier for Eve to break. However, with this scheme, the client would
have to send either the password or the sessionBase, which would give
Eve the guns needed to do replay attacks.
**) You can even solve this, but this would require an implementation
of a symmetric encryption and decryption algorithm client-side. I'm
fairly sure you can make TEA-128 (Tiny Encryption Algorithm) more than
fast enough to encrypt your JSON. I wrote a TEA-128 implementation for
WMLScript once. If you want to encrypt GWT-RPC you will need to do
some hacking of GWT source, but shouldn't be difficult. You use
similar tricks to 'sessionBase' above to obtain a shared secret that
is never actually sent across the wire except during the signup/change
password phase.
NB: The devil is in the details. change password is a massive security
leak in these circumstances, because the majority of people get their
email in plaintext. Eve could just go to the website, act like Alice
and request a new password for Alice. Eve now sniffs Alice's email and
sees the 'click here to change your password' link. Alice now follows
this link and sniffs the next email with Alice's temporary password.
Eve is now completely in control. Which means all our efforts in the
previous paragraphs are wasted; it's like installing a vault door for
a front door while your house is made out of plywood.
One solution to this dilemma is to either not allow changes of
password, or to frustrate any attempts to change it with other
measures, including:
delays (giving Eve the chance to notice that a new password has been
requested, logging in with her old password, and your servers knowing
that if this happends, the new password that is about to become valid
must be Eve playing tricks and thus must never become valid. The
question is: How long do you delay? Too short and Alice has no time to
intervene, too long and Alice is going to just stop using your
service).
IP checks (keeping a backlog of the IPs Eve usually uses for your
service, and only allowing new passwords from IPs already frequented.
This is tricky because not everyone has IPs with easy to detect
patterns, and oftentimes Eve is a packet sniffer on the same network
Alice is on anyway, where this wouldn't work).
More questions (asking a 'security question' with 'out of band' (and I
use the term very loosely there) information, such as favourite pet's
name, without which the account would be permanently lost).
Either way, it's a heck of a lot of effort. Which is why I still
suggest that unless you come up with some complete library plugin
solution the rest of us can use, this is far, FAR too much effort.
Even if your developers cost 2 bucks an hour it's probably more
economically feasible to just shell out the 60 bucks or so for an SSL
cert and use that. Shop around; you don't need verisign, they gouge
you. There are other providers.
On Oct 9, 3:19 pm, Martin Portmann <martin.portm...@gmail.com> wrote:
> Thanks for your response. After some thought the idea to implement
> bcrypt password hash on the client side (aside from the numerical
> problems) has another drawback: the need to know the users salt (this
> would add another round-trip to the server).
> After some more research I did not find a bcrypt implementation in
> JavaScript but there are implementations for MD4, MD5, SHA1 athttp://pajhome.org.uk/crypt/md5/and an implementation for SHA-256 athttp://anmar.eu.org/projects/jssha2/
One note:
I've been unable to reproduce the output of pajhome's SHA1 js
implementation with serverside code -- if you're able to do so, (for
any js hash) please clue me in :)
Additionally, keep in mind that sending an encrypted password over a
non-secure channel is no better than sending a plain-text password --
Mallory is common enough that someone snooping the encrypted password
and re-issuing the same login rpc is a valid concern. You do need
client-side hashing to implement HMAC, however. (this design is
described here: http://blog.ciscavate.org/2007/09/creating-a-secure-webauth-syst.html
and the rfc for HMAC is here: http://www.ietf.org/rfc/rfc2104.txt)
The HMAC design described above is secure to all attacks, as long as
it is impossible to decrypt the HMAC digest during a session.
--Rogan
- Seems that jBCrypt can be used in GWT. Some minor changes are needed
(random number generation, int array cloning and missing getBytes).
But it seems as all calculation are done using small integers there is
no number overflow problem.
- The implementation seems to be a magnitude slower than the server-
side implementation.
- To avoid the 'slow-script' warning I did some refactoring
implementing a GWT specific version using IncrementalCommand
I would attach the source files but I can't figure out how to attach
files to a post. Anybody interested may contact me at map at infinitum
dot ch.
As you pointed out, a man in the middle can still replace the
javascript with his own, so you'd still want to download the js file
using a secure channel, in which case you might as well use SSL to do
the login as well. Once you're using SSL, you might as well send the
plain password to the server and save yourself the bother.
Still, it might be the case that you have an SSL provider of the
javascript file (that you trust, for whatever reason) and still don't
want to authenticate over SSL, in which case this script would provide
a high degree of protection.
So what I did is ap partial port of a JavaScript BigInteger
implementation (http://www-cs-students.stanford.edu/~tjw/jsbn/) and a
SRP 6-a implementation in Java and PHP. It is working very well.
BCrypt has still the advantage that you can increase the complexity of
the hash calculation over time. But with some implementation tricks
you can do the same with SRP increasing the key size and storing the
associated parameters per user.
A successful SRP handshake has another advantage because it generates
a session key usable for encryption. So you are able to implement a
poor mans SSL protecting agains Eve and Mallory.
- Martin
> > 3. Assuming we do have a hash algo on the client- Hide quoted text -
I've just started looking at this. In java creating an SSL socket
is straight forward if
you can specify SSL CERT with "javax.net.ssl.trustStore". However, I
have a feeling
that you cannot do this on the client-side with GWT.
Does anyone know of a good (how-to/recipe) article describing this?
On Oct 10, 12:45 am, mP <miroslav.poko...@gmail.com> wrote:
> If you want real security just make the user submit their password
> oer ssl. That is the simplest solution and also the safest.
I'm using MD5 from dojo library (runtime loaded when required) to hash
tokens/password/frobs/app session id/etc, whatever to try
implementation based on flickr mobile authorization solution:
http://www.flickr.com/services/api/auth.spec.html
http://www.flickr.com/services/api/auth.howto.mobile.html
it works with GWT based applications (for example to have flickr based
mashup),
do you guys see any possible leaks in such model?
regards,
Peter
I'm more of a SWT/Swing developer making a GWT only application, so a
dojo library
wouldn't be my first choice. But I'll look at it if needed.
I already have a SSL socket implementation, just need a way to pass
the trustStore into
Java's "javax.net.ssl.trustStore" system parameter on the client
side. IF it could be
done it would literally be three lines of code.
Alan
On Oct 16, 2:57 pm, Peter Blazejewicz <peter.blazejew...@gmail.com>
wrote:
> hi,
>
> I'm using MD5 from dojo library (runtime loaded when required) to hash
> tokens/password/frobs/app session id/etc, whatever to try
> implementation based on flickr mobile authorization solution:http://www.flickr.com/services/api/auth.spec.htmlhttp://www.flickr.com/services/api/auth.howto.mobile.html
SSL handshake/etc, all that ssl layer is done via browser without any
client application interaction (completly transparent). So so from
javascript it cannot be done. If I understand well you're asking about
situation where client manages SSL connectios itselfs, but that does
not apply to web application, maybe to applets,
regards,
Peter
On Oct 17, 2:48 am, alan <alan.sny...@gmail.com> wrote:
> Thanks Peter,
>
> I'm more of a SWT/Swing developer making a GWT only application, so a
> dojo library
> wouldn't be my first choice. But I'll look at it if needed.
>
> I already have a SSL socket implementation, just need a way to pass
> the trustStore into
> Java's "javax.net.ssl.trustStore" system parameter on the client
> side. IF it could be
> done it would literally be three lines of code.
>
> Alan
>
> On Oct 16, 2:57 pm, Peter Blazejewicz <peter.blazejew...@gmail.com>
> wrote:
>
> > hi,
>
> > I'm using MD5 from dojo library (runtime loaded when required) to hash
> > tokens/password/frobs/app session id/etc, whatever to try
> > implementation based on flickr mobile authorization solution:http://www.flickr.com/services/api/auth.spec.htmlhttp://www.flickr.co...
which originated from this thread:
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/cc66751832ec419f
- Brill Pappin
On Oct 2, 9:19 am, Martin Portmann <martin.portm...@gmail.com> wrote:
> I am referring to this document:http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecur...
SSL is a client-initiated server-based encryption system. You can't
run SSL 'on the client', period. If the browser doesn't support it for
whatever reason, that's the end of that. However, all browsers that
are GWT compatible support SSL.
It is not possible AFAIK to set up the hosted mode built in tomcat to
use SSL, but there's no point to this either. That should never be
used as production server anyway.
On Oct 16, 7:55 pm, alan <alan.sny...@gmail.com> wrote:
1. MD5 is fundamentally broken as a hashing algorithm. Period. If
someone wants to brute force an MD5, it's not that difficult. At the
very least use SHA-256, but preferably something more suited to the
job, like bcrypt.
2. I didn't read anything about salts. Meaning, you're vulnerable to
dictionary attacks. MD5 compounds this problem, as the number of DVDs
out there with look up tables for straight MD5s are a dime a dozen.
3. The MD5 code needs to be downloaded over the clear. Mallory (A
Malicious User, with the capability of real-time inspection AND
changing the bytes on the channel) can thus replace your md5.js file
with something that calculates md5, but also posts the plaintext
password to his server as well. However, there is NO WAY to protect
against Mallory, _AT ALL_, without SSL somewhere in the process.
On Oct 16, 11:57 pm, Peter Blazejewicz <peter.blazejew...@gmail.com>
wrote:
> hi,
>
> I'm using MD5 from dojo library (runtime loaded when required) to hash
> tokens/password/frobs/app session id/etc, whatever to try
> implementation based on flickr mobile authorization solution:http://www.flickr.com/services/api/auth.spec.htmlhttp://www.flickr.com/services/api/auth.howto.mobile.html