Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

What would be the best practices for storing access tokens of another api for your users? In particular I'm developing an application with some friends that let's user log into Facebook to both authenticate to our internal REST api and make it able to fetch their friends (and other things).

I was thinking of generating a key and use it to encrypt the long-term access token for the user's Facebook account and possibly other sensitive information. As encryption scheme I'd use AES-256-CBC and the key would be sent to the client, which holds on to it (and refreshes it once in a while). But if I generate that key with any randomness in it, then the user can only use one client. As the other clients would need that key to decrypt the Facebook access token and other data. A solution would be generating the key from something unique during the Facebook log-in, but unfortunately the only such thing I can find is the userid, which I need to find the user's record in the database.

There are actually a lot of topics about this over on stackoverflow, but nothing answers to what I want. What I actually want is to encrypt the Facebook access token and other data using a key that only the client-side knows. The creation of those keys should only be possible when the user authenticates using the Facebook sdk or when the current key is supplied.

Any ideas?

share|improve this question

3 Answers 3

I was at the 10th ISC conference of security and cryptology last week and there I saw someone proposed a method for storing user-pass tokens using Neural Network. He's created a NN that learns user-pass tokens and updated itself using a fast NN learning method. It is a new method and promise security but needs lots of attention on learning.

UPDATE

The paper was in Farsi titled enter image description here it means User Access Control Using Neural Network and chaotic system

(stack doesn't support Farsi characters! I used image instead!!!)

share|improve this answer
    
Got any more information about that proposal? like a paper or title? –  Joren Van Severen Sep 4 '13 at 13:44
    
@JorenVanSeveren It is in Farsi (aka Persian). check paper 197 on list of accepted papers here: iscisc13.yazd.ac.ir/… –  sajjadG Sep 4 '13 at 13:53

The sum of what the client stores and what your server stores must be sufficient to recover the user-specific secret data (e.g. Facebook access token). What the client stores is, mostly, the user's password (the only permanent storage area on the client side is the user's brain, if we want to allow the user to use several distinct machines at will). If I understand correctly, you do not want your server to store the data "as is": in case your server is fully compromised, the user's secrets should still be safe (as much as is possible).

This points to password-based encryption. From the user's password is derived a symmetric key K which is used to symmetrically encrypt a bundle which contains the user's secrets, e.g. the Facebook account. Technically, this would look like this:

  • When the user registers, he chooses his password P and sends it to your server.
  • Your server generates a random salt value S and computes PBKDF2 over P and S, to produce 256 bits of output T. Let's call A the first 128 bits of T, and K the other 128-bit half.
  • The first half (A) is stored in the server's database; this will be used to authenticate users.
  • The second half (K) is not stored; this is the symmetric key for that user. User's secrets will be encrypted with K.
  • When the user logs in, he sends his name and P to your server (over HTTPS). Your server retrieves the salt S for that user (as stored in its database) and recomputes T (using P and S with PBKDF2). If the first half of the recomputed T matches the stored A, then the user is authenticated and the second half of T is K. The server can then decrypt the stored bundle and access the Facebook access token.

With this setup, the server never stores (on its disk or in its database) the cleartext Facebook access token, but it can access it when the user logs in; it is up to the server to remember (in RAM) the Facebook access token as long as it needs it.

Note that when the user changes his password, this also changes K (the server must also generates a new salt S, but even if the server mistakenly did not, K would still be changed); thus, the server must decrypt the stored bundle with the old K and encrypt it again with the new K when the password is changed. This is not hard to integrate because password-change interfaces customarily ask for the old password and the new password, so at that point the server has both.

Also note that when the password is forgotten, the bundle is lost. There is no recovery for that case. If the user forgets his own password, then you will have to do some password reset, which is akin to a new registration; and a new Facebook access token will have to be obtained.


In all of the above, we see that your server still sees the user's password. If your server is fully compromised and hijacked, then the attacker will be able to observe users' passwords and users' Facebook access tokens for all users who log in while the attacker controls the server. Preventing that is much harder. Arguably, if your server presents a Web interface only, where all "intelligence" on the client side is Javascript sent by your server, then it is impossible to do better than what the scheme above does, in that situation.

share|improve this answer
2  
The thing is, the user doesn't have a password for our system. Authentication happens through Facebook and asking for another password (besides the password facebook asks if they aren't logged in) seems overkill. –  Joren Van Severen Sep 5 '13 at 15:30

Facebook Docs: Securing Graph API Requests provides a simple solution.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.