Monday, January 24, 2011

Usability and cryptography

Ostensibly this post started as a demo of how to secure data on windows phone. It still is, but as the code progressed, it became clear that it is unreasonable to expect the average developer to do this correctly. Fundamentally, what cryptographic libraries provide is incomplete from a usability standpoint for application developers: What most developers want from crypto is a locked safe to store data in.

What they get is a set of jagged glass jigsaw pieces from which they have to try and assemble it with little or no instruction. This was fine when the point of a managed crypto api was to let programers with some domain knowledge implement a crypto system. However, the goal posts have moved. On a mobile device, all developers want data security. Thus If one's end goal is to enable this, the current API  is unacceptable.  

When API designers ask developers to assemble this safe, they are asking for it to be done incorrectly. Both the CryptoStream(c#) and SealedOject(Java)  require the developer to handle algorithm selection, mode selection , key generation, IV generation and storage, and data authentication. At every step programmers  can and probably will make the wrong choice. There is more than enough room for developers to hang them selves with these choices. 
  • They could choose DES (here is why not to) 
  • They could use a bad chaining mode (here and and the entry for ECB here)
  • They could use an incorrect  IV  (here )
  • They could fail to sign their data(here is what happens if you forget to)

More than half the the developers  who ought to be reading this probably have no idea what any of those things are and there is no reason why they should. Even if you do and have some experience with crypto, its still easy to make mistakes: I failed to properly authenticate the stored data in the first version of the code ( I didn't mac the IV, just the data).

Beyond that, it turns out that building an idiot proof secure storage system is inviting the world to invent a better idiot. Originally this code merely exposed the PasswordProtectedContainer and left persistence of it  to the developer. As several people who reviewed the code pointed out, this allows for containers that use the same password to be swapped for each-other. At least the academic cryptographers I have worked with would probably take the answer that this is a misuse of the system : all data with ordering constraints should be stored in one sealed object. Indeed, they are correct and I had taken that as a given limitation when I started designing this. However, if our goal is to develop something that actually increases security  on the platform, thats a copout: the system needs to at least discourage this programming pattern.

The linked code is about as good as can be done from managed code in silverlight. It has some limitations, both from a end user usability standpoint and a technical crypto standpoint. 

From a usability standpoint, it makes no sense to ask the user to input yet another password after they have presumably input a password to unlock the phone. Worse, most use cases for this code are probably for storing auth tokens to web-services. At that point one might as well ask the user for the actual password to the service.

Form a technical standpoint, a lot of copes of the key material/ password can be left around and swapped to disk because:
  • The crypto keys are stored -- both by my code and the underlying managed crypto classes -- in the clear in none locked pages as byte arrays.
  • SecureString is not available in silverlight and as such  developers will likely end up storing passwords in strings which can't be erased or at best a byte array which also can be swapped to disk.
  • The password box can easily end up with a copy of the password as a string.
  • The internal state of Rfc2898DeriveBytes possibly can get swapped out  as well.

If any of these things ended up on disk, anyone with physical access ( i.e. the theif we wanted to protect against by securing the data in the first place) could read them and decrypt the data, or at least seriously reduce the key space to the point where a brute force attack is practical on a normal laptop.

The usability issue especially is a large one since if security a pain to use, it probably won't be be used by anyone. Neither issue, however, can really be addressed from the sandbox provided by windows phone.  Further posts will explore both of these sets of limitations and the ideal solution if one didn't have to play in the sandbox.


No comments:

Post a Comment