Comparing Performance of JavaScript Cryptography Libraries

Cryptography is a computationally intensive application and has typically performed poorly in JavaScript. Recent additions of raw binary data access and multi-threading have made encryption/decryption of large data sets in JavaScript manageable. WebCrypto, which provides asynchronous, multithreaded, hardware accelerated, near native performance, has made working with cryptography in web browsers a breeze, at least from a performance perspective.

The subject of this test is authenticated symmetric encryption. For libraries that support modes with integrated authentication, such as AES-GCM or AES-CCM, these modes are used*. Otherwise the non-authenticated mode AES-CBC is used along with HMAC for authentication.

* Although asmcrypto supports AES-GCM, performance is significantly worse than AES-CBC + HMAC. The WebCrypto standard supports AES-GCM, but it is not implemented in WebKit based browsers. Therefore, AES-CBC + HMAC is tested for compatibility reasons.

Libraries tested:

Platforms tested were:

  • Intel i5–4200U based laptop
  • Apple iPad Air 2
  • Tegra 3 T30L based Android tablet
  • Qualcomm MSM8610 based Android phone

Tests are available on jperf.

Tests show that WebCrypto is between two and fifteen times faster than any other JavaScript cryptography library. In real world application, the difference is even more significant since pure JavaScript libraries need to run inside Web Workers or restrict usage to very small data sets to reduce UI thread blocking.

The performance advantage would be even greater if not for the lack of WebCrypto AES-GCM support in WebKit based browsers. While performance of AES-CGM and the non-authenticated AES-CBC is comparable, requiring authentication results in five times faster encryption and three times faster decryption with AES-GCM than with AES-CBC-HMAC-256.

AES-GCM is not hardware accelerated on the current Apple CPUs and not supported in CommonCrypto, the iOS/OSX low level cryptography library. Therefore it is unlikely that fast AES-GCM implementation will be added to WebKit in the near future and, in my opinion, any applications that require compatibility with WebKit based browsers and/or iOS devices should use AES-CBC-HMAC.

Edit: I was asked about emscripten compiled crypto performance. Emscripten compiled NaCl Xsalsa20-Poly1305 does about 8MB/sec on Chrome i5–4200U. While the comparison is not exactly apples to apples, performance is poor compared to WebCrypto.

To summarize, WebCrypto is a great addition to the JavaScript ecosystem. It is very fast, easy to use and supported on most web browsers. If your web application does not need to support Internet Explorer 10 or lower, and Safari 7 or lower, WebCrypto might be a good solution for your cryptography needs.

Additional resources:

Note: WebKit bug previously mentioned in this article has been fixed. Many thanks to Scott V.