Public key encryption with ease
We were invited to this year's Appshow 2017 in beautiful Milan, Italy to give an overview of our experience developing native Public key encryption for mobile apps. This is a brief summary of the talk in case you missed it.
Source code available
Just in case you cannot wait to see some code - the source code referenced in this article is available! https://github.com/expressflow/securebeam-core
PKI is solved - is it?
Implementing a strong Public Key infrastructure seems to be rather easy these days - there are a ton of helper libraries available and the topic has great visibility these days.
But when it comes down to the nitty-gritty coding details of Public Key Encryption (like Key generation, RSA Encryption, Padding, etc.) things get complicated.
Adding the User Experience topic on top of complicated Public Key encryption implementation makes developing secure apps even more cumbersome.
Let's shed some light in all this mess.
RSA encryption just works on fixed length data
Due to the fact that RSA encryption with - f.e. 2048-bit key length - just works on 245 bytes of message length, the data to encrypt needs to be quite short. Too short for most of the data of interest (like confidential documents, private photos and the like).
So to sum it up: 245 bytes is way too short for encrypting arbitrary data directly with RSA.
Let's introduce symmetric key encryption to combine the best of both worlds. The confidential data is encrypted with the symmetric key - which can be generated using a secure KeyGen - and this symmetric key itself is then encrypted with RSA and shared with the other participant.
Ok, so these are the conceptual basis. But how about the implementation details for Android and iOS?
Compatible Encryption between iOS and Android - is it possible?
Well, sort of. There are several caveats you have to think of. Let's summarize the most important ones (and provide links to further details about the implementation details):
- [Android] Java requires the developer to activate a Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy if AES key length is longer then 128 bit.
- [Android and iOS]Compatible Padding of the encrypted data between iOS and Android is complicated. Use PKCS1 Padding!
- [Android and iOS]Compatible Encryption (both: symmetric and asymmetric) is complicated
- [iOS]Strictly adhere to Apple’s own CommonCrypto Library.
All other libraries bear the risk of App Store Rejection!
Finally a word about UX
We started right away with the implementation of the app, because we are engineers and love to code, right?
We made the encryption process transparent, took great care of making the app performant and implemented a very technical first version of the app.
The result was a disaster - from a UX perspective. Take a look at the above image:
It's way to technical, has no intuitive User Interface and lacks completely any kind of Call to action.
As a small test: Looking at the above image for just a few seconds: How would you add a new file?
Extremely hard to answer. And so was the result in the first user tests:
So we sat down with a UX expert, integrated user feedback, improved guidelines, iterated.
And we iterated a lot.
The above image is the current version of SecureBeam for iOS.
It's still not perfect and requires a lot more work to do. But it's a beginning. And we learn. Every day, from the feedback of our users. And we learn from this feedback. Every day. A lot.
Public Key encryption done right is tricky. But it's doable. And absolutely worth it. We share our insights as we belive other App developers might be interested in our insights we found during the development of SecureBeam.
But the best technical solution is worth nothing if the User interface is not intuitive. And it is not a do-it-once approach, you have to learn from your users continuously.
Thanks for your interest!