Tuesday, April 29, 2008

Doubly Encrypted for Extra Safety

Floating 'round the twitterverse today was a new service called twittersnooze. The possibilities for twitter apps seem endless, and considering how easy and, well, fun the api is to play with, I'm sure there will be many more.

Among other nice features, I applaud the auther's honest disclosure that "TwitterSnooze stores passwords on the DB". Currently as the twitter api is written, this is a necessary evil for an application of this sort. If you want to authenticate, you need the user's password in plaintext.

However, there is a way around this that I think twitter, and other web sites that have apis should consider doing (I think lastfm does this, but I'm not sure). Basically I am suggesting that the site doubly encrypt their passwords, and make the first level of encryption publicly available. How exactly would this work? In this example, I will describe a double encryption scenario using salted md5, and I will use twitter and twittersnooze as api providers and consumers:

  • When the user signs up for twitter 2 salts are generated (salt1 and salt2) and the password (plaintext) is then encrypted as: md5(salt2 + md5(salt1 + plaintext))
  • Both salts will be stored in the twitter's user table, as will the result of the double encryption.
  • Salt1 will be made available through the api without authentication.
  • When a user signs up for twittersnooze, twittersnooze will make an api call to retrieve salt1. It will then encrypt the user's password as md5(salt1 + plaintext) and store the hash in it's user table.
  • When twittersnooze needs to authenticate as the user, it sends the hash that it has stored. Twitter then applies md5(salt2 + hash) and checks that it matches it's own user table.
  • Viola! No plaintext passwords stored anywhere!
Some other benefits:
  • Twittersnooze can now use the twitter password for its own user accounts, saving the user the trouble of creating a new account.
  • The plaintext password never has to be transmitted over the wire between twittersnooze and twitter.
  • If salt1 == salt2 then there is no additional storage requirements for twitter.

Of course, there are other approaches. The first one that comes to mind is to generate api keys for every user, which can be fetched via their api. This is certainly better than nothing, but has the drawback of requiring that the plaintext password be sent over the wire for authentication when the api key is fetched.

Please note that I am not suggesting that applying md5 twice is stronger than applying it once. Thats a different issue and I think thats what people usually mean when they say "double encryption". Rather, I am suggesting that doing it obviates the need to store plaintext passwords.

If tweetersnooze's database was compromised under this scenario, it would still be a security breach for twitter. It would not, however, impact the naive user who uses the same password for twitter that they use for their online banking.

Any thoughts?



Blogger sgrove said...

I was thinking along the same lines - this would at least take out the plaintext portion on any server.

Just seeing some user's account information sitting in plaintext in the database bothers me a bit, since it's an additional liability to the users if my database is compromised.

Let's hope twitter implements something along these lines in the near future.


3:46 AM  

Post a Comment

<< Home