High speed, public-key cryptography in JavaScript (part 1)

Rolando Santamaría Masó
3 min readSep 5, 2018

--

In this article we will discuss through the basics how we can implement “end-2-end secure communications” in JavaScript.
Using a state of art cryptographic library, here we present the basic foundations of a robust cryptographic system.

Photo courtesy of https://pexels.com

The basics

Let’s start by describing two introductory concepts that are required before we start implementing.

Public Key Cryptography

The “Public Key Cryptography” is the cryptographic mechanism that allows the Internet to be secure.

Public-key cryptography, or asymmetric cryptography, is any cryptographic system that uses pairs of keys: public keys which may be disseminated widely, and private keys which are known only to the owner. This accomplishes two functions: authentication, where the public key verifies that a holder of the paired private key sent the message, and encryption, where only the paired private key holder can decrypt the message encrypted with the public key.

Example of systems using Public Key Cryptography:

NaCL & TweetNaCL.js

NaCl (pronounced “salt”) is a new easy-to-use high-speed software library for network communication, encryption, decryption, signatures, etc. NaCl’s goal is to provide all of the core operations needed to build higher-level cryptographic tools.

The NaCL project is being lead by Daniel J.Bernstein, one of the most prominent Computer Scientists of our era.

Optionally you can read Aaron Swartz comment on Daniel J. Bernstein: http://www.aaronsw.com/weblog/djb

Specifically, NaCl uses elliptic-curve cryptography, not RSA; it uses an elliptic curve, Curve25519, that has several advanced security features; it uses Salsa20, not AES (although it does include an AES implementation on the side); it uses Poly1305, not HMAC; and it uses EdDSA, not ECDSA.

NaCL is proven to be secure, as breaking every round of Salsa20 is theoretically more expensive than breaking correspondent AES rounds.
In the other hand Salsa20 was designed with speed in mind, offering great performance even under low speed CPUs. A more detailed explanation of Salsa20 speed is available here: https://cr.yp.to/snuffle/speed.pdf

TweetNaCL

TweetNaCl is the world’s first auditable high-security cryptographic library. TweetNaCl fits into just 100 tweets while supporting all 25 of the C NaCl functions used by applications. TweetNaCl is a self-contained public-domain C library, so it can easily be integrated into applications.

The TweetNaCL.js project brings TweetNaCL to JavaScript and therefore to Node.js and the Web. It uses XSalsa20(longer nonce) stream cipher instead of Salsa20.

JavaScript Benchmarks: https://github.com/dchest/tweetnacl-js/blob/master/README.md#benchmarks

Joining the JavaScript puzzle

Bob encrypts message for Alice

TweetNaCL.js public key encryption example

Alice decrypts message from Bob

TweetNaCL.js public key decryption example

Using pre-computed shared keys

For encryption/decryption sessions between peers, using pre-computed shared keys is recommended:

TweetNaCL.js encryption using shared keys
TweetNaCL.js decryption using shared keys

Maintaining the keys

Public Key

A “Public Key Infrastructure” requires proper solutions for the maintenance and authentication of the users public key. While this process is out of scope in this article, a common solution consist on maintaining the users public key as part of their profile page and make it accessible to their contacts through a directory-like API.

Private Key

Maintaining secret keys is a lot more complicated, as this is a very sensitive piece of information users want to keep in secret. Commonly this process is a user responsibility and somehow the applications implementing public-key cryptography are required to allow the users to enter their secret keys (never transmitting it to the server-side).

Secret keys are often stored using offline secure storage mechanisms or online, using strong symmetric encryption methods such as AES to protect the key. The second method simplifies the process of “injecting” the private key into the application(client-side decryption only), for instance: during the login phase.

Conclusions

In this article we have introduced Public-key Cryptography and how it can be implemented in JavaScript using the TweetNaCL.js library.

Using XSalsa20 instead of RSA, CPU usage and battery consumption are reduced to historical minimums, while keeping strong 256-bit security levels.
— a message for your apps ;)

Digital Signatures using TweetNaCL.js will be discussed on a second post in this serie: read it here.

As always, your feedback is appreciated!

--

--