Hi, I’m Anastasiia Voitova and I gave a talk about cryptography and risk management at Codemotion Milan 2018. I am product engineer in cryptographic software company Cossack Labs – we create developer-friendly software to protect data and to help companies to comply with modern regulations. During my talk, we discussed cryptography in a wide context – not ciphers and keys, but how proper data encryption can help to make your entire infrastructure more secure.

The less the system knows about the data it operates, the more secure it is

So, cryptography is not a magic tool that “makes things secure” because we have selected the right algorithm and long key, but it’s a method of managing the attack surface for the sensitive data. The attack surface is any place in your code, infrastructure, processes, where the sensitive data can be leaked. Cryptography answers the questions about key management, trust schemes, places where data is encrypted and decrypted – things that determine the attack surface.

Software engineers who know the attack surface of their system can monitor it for suspicious behaviour. The more well-defined and narrow the attack surface is, the better monitoring and risk prevention could be.

How to narrow the attack surface? Move the data encryption as close to the place where plaintext is created as possible.

“Separation of duties” for typical web infrastructures

Typical public web applications face many threats: injections, XSS, execution flow attacks, and so on. Sometimes web developers decide to encrypt data in a naive way – encrypting and decrypting it on the web backend side. (Of course, TLS is on and working).

If the decryption key is stored on the web application side (or even in the database) – it’s kinda easy to steal it.

A good idea is to use the “separation of duties” pattern: allow publicly-facing web backend only to encrypt data and move decryption to the separated trusted module.

Simple symmetric encryption won’t work: we should use the combined scheme (symmetric + asymmetric). One of the existing schemes is to generate encryption keys on the web backend: generate a random symmetric key to encrypt the data. Then generate own temporary key pair, use your own private key and the public key of decryption service to encrypt the data encryption key. The last step is to merge all pieces together in the data structure: encrypted data, encrypted key, the public key of web backend. Send and store this data structure in the database.

In this case, a web backend has no keys to decrypt the data. A special decryption module is responsible for data decryption. When a web client wants to get the data, the decryption module reads encrypted data structures from the database. Then it uses its own private key and public key from the data structure to decrypt random symmetric key and encrypted data and returns the payload to the web client. The decryption proxy is a trusted part of infrastructure: we monitor it and its keystore, log access, protect it by firewall and IDS.

It’s just a short overview of the whole scheme, but if you want to understand details or even try it yourself – check the open source repository of Acra.

Such an approach works well in the infrastructure with many micro-services and non-trusted client sides (like web).

End-to-end encryption and Zero Knowledge architectures

In some systems we can dive deeper – into building an end-to-end encryption scheme, so no module inside the infrastructure knows the nature of the sensitive data.

Such a software design approach is known as Zero Knowledge architectures (or No Knowledge architectures). In simple words, everything you do on a Zero Knowledge system is encrypted before it is sent to the server, and the key to the encryption is also never known to the service provider. It’s possible to build Zero Knowledge system for messaging, authentication and even secure documents exchange.

The world already knows many e2ee chats (like Wire or Signal), authentication protocols (like Zero Knowledge Proof protocol) and frameworks (like Hermes or ZeroKit). The attack surface for such systems is quite small: if you use a trusted client side (like mobile apps or HSMs), select strong ciphers and implement key management well, your system is kinda safe.

Well-implemented cryptography gives you control

If you ever wondering what properly implemented cryptography gives you and how to define “properly” for your use-case, the answer is that cryptography gives you the control over the attack surface on your data.

However, except implementing encryption, you also need all those shiny traditional techniques like proper access control, monitoring, logging, rolling out security patches, intrusion detection, firewalls, tunnelling, continuous pen-tests (and so on). All these measures, applied in the right places, make cryptography useful in a broader landscape.