On Wed, Sep 08, 2010 at 05:45:26PM +0200, f...@mail.dnttm.ro wrote: > We do a web app with an Ajax-based client. Anybody can download the > client and open the app, only, the first thing the app does is ask for > login. > > The login doesn't happen using form submission, nor does it happen via > a known, standard http mechanism. > > What we do is ask the user for some login information, build a hash > out of it, then send it to the server and have it verified. If it > checks out, a session ID is generated and returned to the client. > Afterwards, only requests accompanied by this session ID are answered > by the server.
I understand why you're doing this, but it's not really any better than sending the password to the server in the first place via a POST from an HTML form (where the GET and POST of the form happen over HTTPS). The reason there's no real difference is that the script comes from the server, so it could do anything at all (and besides, you'll end up with a password equivalent at some point if all you do is hash the password, but read on). And since you'd still be teaching your users to type passwords into web page elements, you'd still leave your users susceptible to phishing. Still, if this is what really you want, then I recommend that you use SCRAM (RFC5802). SCRAM uses HMAC-SHA-1. You can find implementations of SHA-1 in JavaScript; implementing SCRAM given a JavaScript SHA-1 implementation isn't hard. Note that if mechanisms like SCRAM were provided by the browser, then it'd safe (indeed, good!) to use them. Implementing them in a server- provided script doesn't provide anywhere near as much security as implementing them natively in the browser (or in a browser plug-in/ add-on). If you can afford to develop a browser add-on, then I recommend you implement SCRAM there. The key is to make it possible for users to distinguish web page elements from UI elements of the browser/ add-on -- this is hard. > What we need is a hashing algorithm that: > - should not generate the same hash every time - i.e. should includen > something random elements We calls those random elements "nonces". SCRAM has those. Browsers provide a random() method. > - should require little code to generate SCRAM is rather simple. > - should allow verification of whether two hashes stem from the same > login data, without having access to the actual login data I'm not sure what you mean here. I think you mean that the verifier shouldn't be the password nor a password equivalent, in which case you're completely correct. SCRAM has that, though the server obtains enough information, the first time that the user authenticates, to keep a password equivalent for later use. Also, SCRAM is susceptible to off-line password dictionary attacks. SCRAM is best used over TLS (HTTPS), with channel binding (see below), to defeat passive attacks and to make MITM attacks harder to mount without the user noticing. > We need to implement the hashing algorithm in Javascript and the > verification algorithm in Java, and it needs to execute reasonably > fast, that's why it has to require little code. None of us is really > into cryptography, so the best thing we could think of was asking for > advice from people who grok the domain. "Little code" does not imply "fast". Nor does "much code" imply "slow". If you don't understand this then you have bigger problems than not being into cryptography. You should want "little code" so that development and maintenance are cheap, not so it runs fast. > The idea is the following: we don't want to secure the connection, we > just want to prevent unauthenticated/unauthorized requests. Therefore, You should definitely want to secure the connection. If you don't then your users will be subject to MITM attacks. (But then, your users will be vulnerable to phishing attacks anyways, since they'll be used to typing passwords into spoofable web page elements.) > we only send a hash over the wire and store it in the database when > the user changes his password, and only send different hashes when the > user authenticates later on. On the server, we just verify that the > stored hash and the received hash match, when an authentication > request arrives. Cleartext passwords aren't stored anyway, and don't > ever travel over the wire. > > However, we could not imagine a reasonable algorithm for what we need > until now, and didn't find anything prefabricated on the web. > Therefore we ask for help. Well, you did the right thing in coming to such a list. You should have done more reasearch, but it's not a big deal that you didn't, because as you can see, the real problem is that we don't have a good solution for you (that is, the browsers don't provide what you really need). > br, > > flj > > PS: reusing the session ID is of course a security risk, since it > could allow session hijacking. We're aware of this, but don't intend > to do anything about it other than warn customers/users. Since it's a > web application, its client code is open, and anybody being able to > watch the connection can deduce whatever is needed to hijack the > session, no matter what algorithm is used, unless the connection is > encrypted right from the start. Connection security is however outside > the scope of the web application. We can't encrypt communication in > Javascript for efficiency reasons, it has to be done in a lower layer > (VPN or SSL, for example). It may in theory work using a preshared > key, but it's not reasonable to believe that the application users > will be able to cope with such a mechanism. I don't understand: why not use HTTPS [with server certs]? Granted, you'd still depend on a "PKI" with so many root CAs as to be nearly useless. But even so, HTTPS is much better than nothing. And yes, TLS (SSL) is at a lower layer, but that's not a real problem. Moreover, SCRAM provides for "channel binding", which allows you to bind the TLS channel into the SCRAM authentication, which in turn helps the weak PKI situation. Nico -- --------------------------------------------------------------------- The Cryptography Mailing List Unsubscribe by sending "unsubscribe cryptography" to majord...@metzdowd.com