We are developing a Mobile web app where the users want (and it is a non relaxable requirement) to be logged for a very long time.

The solution we are developing has a web-client part in HTML+JS and a middleware in Java. Storing the users credentials in the middleware is not an option because we do not want to have a single point where some Administrator can get ALL the credentials of the users. So to be short these are the requirements:

  1. Remember me for a very long time
  2. Middleware cannot store users credentials
  3. Auth systems in the Backend of the middleware cannot produce a long time session token
  4. We want to protect the users credentials more than the application access

We know very well that storing credentials in the HTML LocalStorage or Cookies is a very bad security practice, but:

1) Users know that they have a very long time "remember me" and it's their responsibility to log-off (Security vs Usability)

Obviously storing the credentials in plain text in the HTML LocalStorage is not an option because XSS attack can steal the credentials, so we have designed a solution and we want to discuss its security here. A small notice: we'd like to discuss it under a real point of view not an academic vision ;)

a) users put their credentials in a web form b) a JS lib encrypt the credentials with a RSA Public Key (1024) and put the encrypted payload (EP) in the LocalStorage c) the EP is sent to the middleware which decrypt it with the private key and authenticate the users to backend system(s) (there could be many backend system with SSO) - there is a session id to avoid decryption on every call (when the session expires the client resend the EP) d) if EP exists in the client side, the client send it and authenticate again the user e) if the user want to log-off, the client deletes the EP and give the login form to the user

The security point are:

a) on the client side there is only an encrypted stuff with an asymmetric algorithm ==> none can decrypt it b) we consider much harder for an Administrator to put inside the middleware than to steal credentials on the disk c) Every N months we renew the RSA keys and all the users must reauthenticate

The only attacks I can image are:

a) a browser plugin that steal the credentials before the encryption ==> this is true for ALL the web auth forms b) a replay attack: stealing the enc payload permits to authenticate impersonating the real users ==> this is a problem, but the credentials of the users are safe and this balancing the very long rememberme (same problem of very long session)

I cannot imagine other kind of attacks.

I am very opened to all the opinion to improve the security of our solution (but usability is very important...)

  • If your private key is stored in the middleware accessible to admins, all bets re: insider/administrator threat are off. – Deer Hunter Jan 30 '13 at 7:48
  • I do not agree, respect to have ALL the passwords in a file, you need to deploy a new version of the middleware and catch (in the time) ALL the passwords. It's harder but possible (in this sense I agree with you) – robob Jan 30 '13 at 17:02

It sounds like you're making this more difficult than it has to be.

Clearly a random, server-issued key which corresponds to a server-side data element is by far the best solution, and in practice the only solution that any reputable organization employs. But since you want something different, here you go:

Upon login, you encrypt the login information server-side, with salt and some HMAC (and possibly a timestamp), base64 encode the result, and there's your persistent token that you issue to the client. Ideally you should also tie the login to the device somehow; perhaps some sort of static device ID that gets sent to the server and encoded into it.

Then when you need to re-authenticate, your client passes this token to the server, which your server will decrypt, authenticate, and then issue your app a session key as normal.

It's not quite as good a solution as a random, opaque authentication token (which is valuable only as it corresponds to some server-side datastore), but you said that this is impossible for some unknown reason. I would argue that if something as simple and useful as this is impossible, then you're using the wrong software.

As for using asymmetric crypto and browser-based RSA for storing authentication tokens, I can't come up with even one scenario where this is appropriate. But sometimes complexity for complexity's sake has it's own allure.

  • because clients have to be authenticated for a long time, the server key to encrypt/decrypt the BLOB will be persistent on the server for the long same time. So, if I, as an attacker, find the key and all the persisten tokens, then I have ALL the credentials. With Asymmetric key the encrypted BLOBs are distributed on the users mobile and in server memory (but in differente time) when the server side has to decrypt them. Sure If I modify the server code is easy to catch ALL the credentials, but I need much time and know-how to do that. – robob Jan 30 '13 at 17:17
  • You don't store the password in the server-side data store. There's no reason to do that. You simply store the username they authenticated as. – tylerl Jan 30 '13 at 17:32
  • mhhh...probably I was not so clear. Server side need user password to authenticate itself on backend (respect the server side) systems. – robob Jan 30 '13 at 18:00
  • OK, how about this: you store the credentials on the server, but encrypt them with a random key. Encode the random key (not the password) in the cookie you send to the client. decryption only possible when the client shows you his cookie, but the cookie itself has no value without your server. – tylerl Jan 31 '13 at 1:06
  • This is a very good alternative. I see an advantage: speed for encrypt and decrypt (asymmetric is slow). The disadvantage is that the protocol need a more (little bit) complex handshaking phase and my soultion can be used without SSL too (because credentials do not leave the mobile). At this point I prefer to use Public key stored in the client to cipher the credentials and load the server to decrypt with private key. I'll experiment this and if I have bad performance I'll use your idea. Thanks to you. Please add your comment as an answer to get more score. – robob Jan 31 '13 at 7:44

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.