Now supports Off-the-record encryption

I'm happy to announce that the 0.7 release of Converse.js now supports Off-the-record (OTR) encrypted messaging.

The OTR protocol not only encrypts your messages, it provides ways to verify the identity of the person you are talking to, plausible deniability and perfect forward secrecy by generating new encryption keys for each conversation.

How this works is actually fascinating. The encryption keys are generated via a Diffie-Helman exchange. On youtube there is a video with a very simple and intuitive explanation on how the Diffie-Helman key exchange works. For more details, you can also read the OTR version 3 protocol spec.

I was able to add OTR support for converse.js by using Arlo Breault's excellent otr.js library, which is also used in Cryptocat and Diaspora.

Many thanks go out to him for this.

Note Note: Arlo cautions that the otr.js library has not yet been properly vetted by security researchers and shouldn't be used in life or death situations. This word of caution applies doubly so to its integration into converse.js! I'm not a professional cryptographer and this should be seen as an experimental feature. Caveat emptor!

Screencast Note: For detailed fullscreen, make sure that video quality is set to HD, by clicking the gear icon on the video player.

On Javascript Cryptography Implementing Cryptography in Javascript is relatively controversial and in 2011 Matasano security wrote a scathing criticism called Javascript Cryptography Considered Harmful. I read that article before I started working on OTR support for converse.js and I'd like to go through some of its criticisms step by step to explain how they might apply to converse.js and what I've done to mitigate them. If you're going to read on, it would make sense to go read that article first. Secure delivery of Javascript to browsers being a chicken-egg problem Their criticism appears to apply to the case where developers use Javascript cryptography to implement secure communications with a server instead of relying on a standard protocol such as SSL/TLS. The OTR crypto is not trying to compete with or replace SSL/TLS. Sending data in the clear with normal HTTP is not secure and should be avoided. Therefore, if you are going to use OTR with converse.js, always make sure that the site users HTTPS (i.e. SSL/TLS). Ideally you would also want a mechanism to sign the Javascript and then verify it's authenticity once it's been downloaded. This can be done with code that runs in browser extensions (like Cryptocat does), but (AFAIK) unfortunately not with browser-agnostic javascript (like converse.js). This looks to me like the achilles heel for browser javascript crypto. Besides the webserver serving the Javascript, it's also important that the BOSH service you use employs SSL/TLS, as well as the XMPP server the BOSH service connects to. The XMPP community is on a drive to secure all the major public XMPP servers. See the Manifesto created by Peter Saint-Andre and signed by many in the XMPP community. On http://xmpp.net they let you test the security of servers on the Jabber/XMPP network. Besides using javascript served via TLS, you can also download the converse.js tarball to your computer, unpack the files and access them directly. The index.html page will open up a page identical to the one on http://conversejs.org. Browser Javascript being hostile to cryptography The prevalence of content-controlled code. If the website fetches javascript from thirdparty websites (for example to serve advertisements), then you not only have to trust the server to serve non-malicious code, but also all those 3rd party servers. The solution is to not use such a site for secure communications. Clear your cache regularly, Use hosts you trust, or as I've mentioned above, bypass the webserver entirely by using converse.js from your own filesystem. The malleability of the Javascript runtime. Javascript is indeed very malleable. Methods and attributes on objects can be replaced during run-time (see Duck Typing and Monkey Patching), This makes it easy to inject malicious code into Javascript. However, in order to do this, the attacker's code needs access to those Javascript objects, and fortunately Javascript provides a way of hiding sensitive objects inside closures, thereby preventing an attacker from accessing and manipulating them. Simply put, a closure defines a limited scope for objects, variables and functions which when used correctly, cannot be accessed from any other Javascript code. Any variables, objects or functions defined locally inside another (parent) function (with the var ) keyword, are not accessible outside of that parent function. If the parent functions is anonoymous (is not referenced anywhere) or the child function's runtime outlives the parent's, you have a private, enclosed scope with data that cannot be accessed from outside that scope. All the data in converse.js is encapsulated inside such closure. The lack of systems programming primitives needed to implement crypto. Matasano claims that Javascript lacks a secure random number generator RNG. Without having authoritative knowledge on whether their claim is valid, I'll refer you to this blog post by Nadim Kobeissi (author of Cryptocat), where he claims: This is in fact not the case. window.crypto.getRandomValues() is a secure random number generator available in JavaScript, and supported by major web browsers. His blog post is well worth reading, and he also addresses some other criticisms for which I didn't have anything to add.