Unlocking encryption for developers

How years of trying to build secure, encrypted apps led us to build an open-source key management platform instead.

Thursday, July 6, 2023

enigma codebreaker Photo by Mauro Sbicego

Early experiments

About 3 years ago I was working as a developer building enterprise SaaS, and spending my nights and weekends running experiments with various projects around security and privacy. Nimish was working as a security researcher, and we were natural co-conspirators on these projects.

A common theme in all our projects was encryption. Our very first foray into this was a simple encrypted pastebin called Lockbox. We wanted a quick and simple way to securely share API tokens, DB passwords or some other sensitive credential while at work, so we built one. We used the browser native Web Crypto API to do the encryption with AES, and were impressed with how easy it was to get up and running with pretty strong cryptography without having to use any third party libraries or packages. All we had to do was figure out what encryption key we were going to use (and be sure to use a random, unique nonce).

We opted for a string of random words from the bip39 wordlist which would be easy to communicate verbally, and could be converted into a key via PBKDF2. We encoded the words in a url fragment to create a shareable link that looked like https://lockbox.space/#permit-clean-find-blade-shift, and it worked pretty well for our use-case.

lockbox Lockbox

Our first go at building software with encryption went surprisingly smoothly, we couldn't help but wonder why more developers didn't use it. Why weren't more apps using encryption for sensitive data? 🤔

A few months later, I was building an auditing app for one of India's largest NBFCs. We were almost ready to ship, but the client decided at the last minute that they wanted us to encrypt all file uploads before they were stored in S3. "No problem!" I thought, with our recent experience of Lockbox still fresh in my mind: "should just be a couple of extra days, boss!". I used libsodium this time to quickly implement the encryption and decryption logic server-side, but soon it came time to figure out the encryption keys and with that came a flood of questions with not a lot of answers: How do I create the key? Where do I store it? How do I monitor key usage? What if I need to rotate the key? How do I avoid vendor lock-in with AWS or some other cloud provider?

Several late nights and heated discussions later, we figured out a scheme that would work and were able to finally ship it to the client, albeit a couple of weeks late. We were starting to figure out why encryption, especially for enterprises, wasn't as simple as using WebCrypto or libsodium.

A couple of years on, Nimish and I were working on a new project — a digital identity wallet. We were frustrated with the poor UX and paywalled security features of existing password managers, and after looking at their underlying crypto, we knew we could do better. Keyspace began with us sketching out the security model and cryptographic scheme. At its core was the idea of self-sovereignty — the idea that users would have complete control over their keys. We set up a scheme to derive encryption and signing keys from a 12-word mnemonic phrase that users could write down and store. The encryption key would be used to encrypt wallet data (logins, notes etc) and the signing keys would be used to sign challenges and authenticate with the backend. We spent weeks iterating on this key derivation protocol before we were happy with it.

With the goal of improving on the security of existing password managers, we also found other ways to strengthen the security of Keyspace. We used Argon2 instead of PBKDF2 for key derivation, XChaCha-Poly1305 over AES for symmetric encryption, and created our own authentication scheme based on cryptographically-signed challenges, which meant not having to store any password hashes in the database. While Keyspace eventually achieved significant success and gained popularity within the community, it further emphasized the inherent complexity of implementing encryption in software.

lockbox Keyspace

Key takeaways

The picture was becoming pretty clear at this point, and we finally had an answer to the question we were asking ourselves back in the Lockbox days. While tools like WebCrypto and libsodium are invaluable resources for building encryption into software, they are only half the story. Any attempt at a real-world implementation quickly reveals hidden complexities and nuances that are beyond the scope of most developers who aren't security experts. It seemed obvious now why encryption wasn't more ubiqutous as a defense against data breaches and malicious actors. There were still important problems that needed solving before engineering teams and companies could seriously consider encryption as a realistic strategy to protect themselves and their customer data. We sat down and listed out the barriers to the adoption of encryption, as we saw it.

Encryption is a minefield

WebCrypto and libsodium give developers powerful primitives to work with, but any non-trivial encryption scheme is inherently fragile — a single mistake can undermine the security of the entire scheme. There are a lot of decisions to make and each one requires careful consideration, from the choice of cryptographic algorithms to the nonces, encoding and decoding of data, securely generating psuedorandom numbers etc. These choices depend on the threat model, the operational environmenmt and capability of the hardware and software on which the system must run. Using an existing solution that has solved all these problems is far preferable to re-inventing the wheel.

Key management is critical

The strength and viability of a cryptographic scheme hinges on the key management strategy. Keys need to be securely generated or derived, and careful consideration is needed when deciding how and where to store them. Keys must never be stored in plaintext or along side the encrypted data they are meant for. Keys can be leaked or accidentally committed to version control, so it must be possible to easily rotate them without having to re-encrypt everything.

Transparency and observability

The ability to audit and verify the security model and implementation being used are non-negotiable and are critical to the trust of the system. Open source is the only reasonable way to ensure this. In addition, the ability to keep track of key-usage in real time is invaluable to making sure a system is continuing to operate securely. Being able to log every time a key is invoked to decrypt data helps protect against incidences of key leakage compromising the system.

Building Phase

If we wanted to realize the dream of encryption as a standard for modern software security, a solution to these problems would be needed. Most engineering teams don't have the security-specific domain knowledge to roll their own key management solution, and would rather spend their time building features. Developers are also weary of the vendor lock-in that comes with using canned KMS solutions from cloud providers. We felt we were in the perfect position to take this challenge on, having spent the previous few years grappling with these problems and building solutions ourselves.

Phase is our attempt at unlocking the potential of encryption for app developers. We took all the lessons we learned from trying to build encryption into hobby projects, open-source apps and enterprise software, and combined them into a single solution — an open-source platform for managing keys, tracking key usage with logs, and SDKs to easily integrate with any application. We believe that encryption is the best defense against data breaches, and that putting the tools to build secure software in the hands of developers is the path to greater adoption and a more secure internet. To this end, we've built Phase with the following key priciples at the core:

  1. Open source: Any cryptographic system should be transparent in its design
  2. Always Encrypted: Data should be encrypted at all times unless it is being actively computed upon
  3. Decentralize the keys: Root keys should be held by users rather than centralized platforms
  4. Security at Day 0: Security tools should be in the hands of developers and be an integral part of application development
  5. Defense in depth: Deploy multiple layers of defense to raise the bar for attackers

phase-console Phase Console

It is early days for us yet, and we have big plans for the future of the platform. We're looking forward to expanding the feature-set of Phase and creating more tools for developers to build secure apps with encryption. If you would like to contribute and get involved in the community, join us on GitHub and Slack.

CLOUD

The fastest and easiest way to get started with Phase. Spin up an app in minutes. Hosted in Frankfurt 🇩🇪

SELF-HOSTED

Run Phase on your own infrastructure and maintain full control. Perfect for customers with strict compliance requirements.