Skip to content
This repository has been archived by the owner on Jan 15, 2021. It is now read-only.

Investigating Javascript TDH

yaronyg edited this page Oct 8, 2014 · 4 revisions

Generating a public/private key pair (preferably RSA using OpenSSL)

Why RSA?

For now we want to start playing with RSA because the security implications of it are much better understood than with ECC. the main issue with ECC is which curves are being used and who generated them. There are theoretical attacks where if a curve in generated in a certain way then it can itself act kind of like a public key that if someone else has the private key for they can break/weaken all keys generated with that curve. Until that situation is figured out we are going to stick with RSA.

Note that there is a real price for this choice. Current thinking is that minimally secure RSA is at least 2048 bit and that 4096 bit is better. The issue is that as quantum computing comes online RSA is particularly susceptible to the massively parallel strategies that quantum computing supports. In fact part of the reason for wanting ECC in the first place was that it's design is believed to be more resistant to quantum computing attacks. Because of the nature of the types of secrets Thali protects we need forward secrecy for many, many years. So 4096 is probably the minimum safe bet.

This means our keys are longer and our key exchanges are more expensive. So we really want to move to ECC, but only once the curve situation is better understood.

What approaches are available in Node?

In investigating potential libraries I saw three approaches:

  • Pure Javascript - this library seems to be the basis for a lot of work on pure Javascript crypto libraries. For security reasons I'm hesitant to rely on these libraries. It just isn't clear to me if these libraries are getting the level of crypto analysis that openssl is. But I'm happy to be educated into believing I'm wrong on that point.
  • ssh wrapper - A few libraries wrap ssh and use ssh-keygen. This is a fine approach since ssh gets lots of crypto love. But I have a predilection for openssl because of its close association with Node. Since we are going to have to figure out how to get node running everywhere I would rather only rely on dependencies that I have to have anyway (like openssl) rather than bring in new binaries such as ssh that I don't otherwise need.
  • openssl wrapper - A few libraries just wrap openssl.
  • openssl directly - There is nothing that stops us from inside of Node just spawning a command line and calling openssl genrsa outselves. There are always little gotchas in doing that so if I can find a library that handles the gotchas, awesome. Otherwise that's exactly what we'll do.

Why OpenSSL?

What we want is a secure and ideally fast way to generate RSA private/public key pairs. The key here however is security. One of the key aspects of security is to use a well known, heavily investigated library whenever possible. In the node world that would be openssl. I recognize this might seem strange in light of Heartbleed but the reality is that something like Heartbleed would never have been found in most libraries because nobody is looking.

So my ideal library is just a Javascript wrapper around the openssl genrsa function (or just calling the function directly).

OpenSSL Key Generation Libraries

Dates are as of 10/8/2014

Library Name License Downloads in last month Last Update Notes
Ursa Apache 2.0 13,592 2 years ago Depends on OpenSSL 'normal' not the apparently 'light' version that ships with Node. Which means if we use this library we have to recompile openssl on every platform we run on. Ick. Also Ursa is apparently no longer being maintained!
nrsa NA 41 2 years ago Seems like a ghost town, will have to stick with Ursa for now.
raw-rsa MIT 29 1 month ago Seems like a very low level wrapper around openssl but I'm having trouble reading the C++ code
openssl-wrapper MIT 12,298 6 months ago This is a command line wrapper for openssl genrsa. Not fancy but takes care of a lot of the drama for us.

Other approaches to key generation

The following are libraries that show up but don't do what we want, I just include them here for reference purposes. Keep in mind that I reviewed these pretty quickly just because of the overload of possible options. So I apologize if I went to fast and misunderstood how one of these projects actually works.

  • ssh-keygen - A ssh-keygen wrapper.
  • ssh-keygen2 - A nice wrapper around ssh-keygen which probably could do what we want but if possible I'd like to stick with openssl since it is 'native' to Node.
  • rsa - No one has touched it in 3 years and no one seems to be using it.
  • rsa-json - I think it generates a rsa key pair as a JSON blob. It is in pure Javascript which isn't a goal since we would like this code to be reasonably fast and I know from experience that even C based key code on Android is pretty slow.
  • keypair - Another pure Javascript crypto library. Doesn't look as active as node-rsa.
  • node-rsa - Another pure Javascript library for generating RSA keys and handling encryption. It's actually pretty cool but given perf issues and my general desire not to use anything but the most mainstream of mainstream crypto libraries I'm going to skip it for now. But it looks more complete and active than rsa-json.
  • cryptico-js - Another pure Javascript crypto library.
  • keypair - This generates RSA keys using pure Javascript but in the PEM format which isn't what we need.
  • jsjws - A node wrapper around the JSON Web Signature library that uses URSA underneath. My past sins come back to haunt me. :)
  • rsautl - This is a wrapper around openSSL rsault which is used to use RSA keys to sign things.
  • crypto - This is Node's built in Crypto support. It doesn't seem to actually support generating keys. It does support Diffie Hellman key exchange but that's another story.
  • cryptico - I believe this is Javascript based and generates public keys as well as handling encryption and decryption.
  • certify - A wrapper around the Javascript keypair library that generates X.509 SN.1 key pairs.
  • pripub - There is no link to a repository and no downloads, I'm not even clear what it is.
  • jsencrypt - This assumes you call out to openssl directly and then do key stuff so it's not quite appropriate.

Putting the public key into a X.509 cert

One obvious way to do this is to use openssl-wrapper to call into openssl's x509 function. But the docs for openssl's x509 aren't much fun. It would be nice to have something less fiddly to play with.

  • x509 - it only parses x509 certs, it doesn't generate them. Still, it could be useful for testing purposes.
  • x509-keygen - generates X.509 certs by a spawn to openssl. But really we are already using openssl-wrapper so I don't see the point.

Another option is forge. It is apparently a complete implementation of TLS in Javascript. It's an awesomely cool idea but I'm not quite ready to make that leap yet. I do plan to use it for testing though.

Clone this wiki locally