Matomo

Introducing Themis | Cossack Labs

🇺🇦 We stand with Ukraine, and we stand for Ukraine. We offer free assessment and mitigation services to improve Ukrainian companies security resilience.

List of blogposts

Introducing Themis

We are proud to present Themis, a novel cryptographic services library.

Every good work of software starts by scratching a developer's personal itch. (The Cathedral and the Bazaar)

What is Themis?

Themis is a high-level cryptographic services library: a library that provides easy to use, highly abstracted set of functions for solving real-world security problems. We would like you to focus on building your software with security taken care of by professionals, instead of scrupulously assembling the building blocks of cryptosystems, resolving implementations, platform availability, vulnerabilities, and performance constraints yourself.

Themis is designed to provide complicated cryptosystems in an easy-to-use developer infrastructure suitable for modern rapid development. It is an Open Source, Apache 2.0 licensed product that you can use free of charge, contribute code to, or use in your own work.

Themis will provide a wide set of security instruments. The first three such instruments implemented in the current, 0.9 release are:

  • Secure Message: a simple encrypted messaging solution applicable to a wide range of applications.

  • Secure Session: a safer, session-oriented messaging solution with better security attributes (at the cost of some stricter demands in its implementation).

  • Secure Cell: a multi-mode encrypted container, suitable for storing anything from encrypted files to database records and format-preserved strings.

Themis is designed with ease of use in mind. From our experience of modern languages and elegant frameworks, we wanted to have cryptographic services with easy-to-use interfaces, which don't require complicated sequences of actions to set up ciphers, validate parameters, etc. Everything is handled within the framework, so the chance of introducing errors and breaking the overall cryptosystems is minimised.

Modular and Efficient

Themis is built around modularity: every layer is a set of abstractions with its own set of risk mitigation techniques and test suites. This way, we plan to avoid massive refactoring when dependencies change. Equally, we intend to isolate risks on each layer and limit error proliferation.

Themis architecture

Why we have started Themis

Themis is our internal platform for developing security procedures in future products and we want those to be built on a solid foundation. We needed an efficient cross-platform library to abstract cryptographic procedures from the implementations of algorithms, to combine elementary steps into cryptosystems, and to address common security scenarios in an easy-to-use form.

As we could not find an existing library that completely matched our vision of what we needed (while we have much respect for the elegance, innovation and approach of Daniel Bernstein's NaCl Project, we felt its narrower scope and limited set of platforms and interfaces did not quite fit our needs), we decided to make our own project Open Source and share the results with the community.

What Themis does

Themis provides high level languages such as Objective C, Java, PHP, Python, or Ruby with a set of objects that implement some specific security procedure each. The current version includes three objects:

  • Secure Message: a sequence-independent, stateless, contextless messaging system. Works best for cases which are low-bandwidth and don't require frequent sequential message exchange or complex APIs.

  • Secure Session: a sequence- and session-dependent, stateful messaging system. This works best for RPC, IPC, message and data exchange, socket-like datagram, and event-passing layouts.

  • Secure Cell: a multi-mode protected data container, can be used on files, SQL records, or any form of structured data record.

What sets Themis apart

  • Themis is simple. Themis is built around the ease of use. Each high level language interface is tested against 'native' programmers' expectations. Code style and syntactic sugar are adjusted according to the best practices of each language and validated by our security team so that usability doesn't impact security.

  • Themis is modern. The design of our cryptographic stack and our approach to implementation and modularity is intended to reflect the best practices in current cryptography using algorithms and techniques based on their track record and risk assessments based on modern attack scenarios.

  • Themis is widely available. The set of high-level languages, in which Themis is available, will grow with each release. We will also be adding more platforms and architectures. Themis is written in ANSI C and designed to build everywhere so if Themis is not available for your platform right now - it will be soon.

  • Themis is mobile, server or anything you make it. Themis is already multi-platform, available for mobile clients, servers, or whichever way you choose to use it. Themis can be used in any network layout. It is threaded and concurrency-friendly.

  • Themis is built with users' needs in mind. We've been in the 'consumer’ developer’s chair for quite some time using all kinds of less-than-perfect tools.

How it works

Themis is built around the ease of use. Let's say we have a client-server communication infrastructure:

It is represented by Python server built with Tornado framework:

import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
    def post(self):
        self.write(self.request.body);
application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(26260)
    tornado.ioloop.IOLoop.instance().start()

and Python client:

import tornado.ioloop
import tornado.httpclient;

http_client = tornado.httpclient.HTTPClient();
try:
    response = http_client.fetch(
        tornado.httpclient.HTTPRequest("http://127.0.0.1:26260", 
        "POST", 
        None, 
        "This is test message"));
    print response.body;
except tornado.httpclient.HTTPError as e:
    print("Error: " + str(e));
except Exception as e:
    print("Error: " + str(e));
http_client.close();

To add Themis Secure Session cryptography (the most complicated and demanding object - others are even simplier than this) into this setup, you have to perform 4 steps:

Step 1. Client/server: Import the library, initialize an object

from pythemis import ssession;

class transport(ssession.mem_transport):
    def get_pub_key_by_id(self, user_id):       #callback function
        # retrieve peer public key form file, database, etc. by peer id
        return server_pub; 

session=ssession.ssession("local id", local_private_key, transport());

Step 2. Client side: initialize the session

init_session_message=session.connect_request();
#send init_session_message to server peer

Step 3. Client side: wrap message being sent in object's wrap method

wrapped_message = session.wrap(message);
#send wrapped_message to peer

Step 4. Server side: wrap message being received by server into unwrap method

res, message=session.unwrap(received_message);
if res==message.is_control:
     # receive correct control message. message must be send to peer as is
else:
     #proceed with plain message

Here's how Tornado server with Themis will look:

from pythemis import ssession;
import tornado.ioloop
import tornado.web;

class transport(ssession.mem_transport):
    def get_pub_key_by_id(self, user_id):           # callback function
       # retrieve peer public key form file, database, etc. by peer id
       return pub; 

session=ssession.ssession("server id", server_priv, transport());

class MainHandler(tornado.web.RequestHandler):        
    def post(self):
        message = session.unwrap(self.request.body);#decrypt received message
        if message.is_control:                      #session is not ectablish yet
            self.write(message);                    #send unwraped message 
                                                    #to client as is
        else:                       
            print message;                          #print accepted plain message
            self.write(session.wrap(message));      #encrypt and send reply message 
application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(26260)
    tornado.ioloop.IOLoop.instance().start()

And this is what the client side will look like:

from pythemis import ssession;
import tornado.ioloop
import tornado.httpclient;

class transport(ssession.mem_transport):
        # retrieve peer public key form file, database, etc. by peer id
        return pub; 

http_client = tornado.httpclient.HTTPClient();
session=ssession.ssession("client id", client_priv, transport());
try:
    response = http_client.fetch(tornado.httpclient.HTTPRequest(
        "http://127.0.0.1:26260", 
        "POST", 
        None, 
        session.connect_request()));                #send initial message to server
    message=session.unwrap(response.body);          #decrypt accepted message
    while message.is_control:                       #if status==1 then session 
        response = http_client.fetch(tornado.httpclient.HTTPRequest("
        http://127.0.0.1:26260",                    #is not established yet
        "POST", 
        None, 
        message));                                  #send unwrapped message 
                                                    #to server as is
        message = session.unwrap(response.body);    #decrypt accepted message

    response = http_client.fetch(tornado.httpclient.HTTPRequest(
        "http://127.0.0.1:26260", 
        "POST", 
        None, 
        session.wrap("This is test message")));     #wrap and send inform message
    message = session.unwrap(response.body);        #decrypt accepted message
    print message;                                  #print accepted plain message

except tornado.httpclient.HTTPError as e:
    print("Error: " + str(e));
except Exception as e:
    print("Error: " + str(e));
http_client.close();

When built correctly, Themis shouldn't take longer than a couple of minutes to integrate into your software architecture. That's what it was built for.

Getting Themis

is as simple as doing:

git clone https://github.com/cossacklabs/themis.git

Diving deeper

Interested enough to read to the end of this long article? Want to know more?

P.S. If you're looking for new ideas, this is the right place. If you're looking to implement security, apply for our Customer Success Program. If you're looking for ready-made solutions, consider also looking into Acra, Hermes, or Toughbase .

Contact us

Get whitepaper

Apply for the position

Our team will review your resume and provide feedback
within 5 business days

Thank you!
We’ve received your request and will respond soon.
Your resume has been sent!
Our team will review your resume and provide feedback
within 5 business days