James Stanley

How to use bitaddress.org securely (spoiler: use IPFS)

Wed 10 May 2017

Bitaddress.org is a single-page web app for generating Bitcoin paper wallets. It's a great tool, and runs entirely client-side so (in theory) you can audit the code and don't have to trust that the server is not stealing your keys.

The Problem

Unfortunately, unless you download the code and host it yourself, you have to audit the code every time you use it, otherwise the server could simply start shipping malicious Javascript at any time. This could be because the author has moved over to the dark side, because he has been coerced by criminals or his local powers-that-be, or simply because his server has been compromised.

The Solution

Fortunately, with IPFS, we can do better. (IPFS is a distributed content-addressable storage system that is web-compatible; it's basically bittorrent for the web).

With IPFS, we only need to audit the code once, and then we know that every time we access the same IPFS path, we are getting exactly the same content, and nobody at all can modify it, short of breaking SHA256. We don't even need the original hosting location to stay online: as long as anybody in the network still has the content, we can continue to retrieve it. Since we know the content is correct, we don't need to care about its location.

Bitaddress.org on IPFS

The IPFS path for bitaddress.org (from commit 72aefc0) is /ipfs/QmYz4bkhtdkGRLFtago2hoNucrfUy5bHwrun8N8XJrrKWA

The astute will observe that this hyperlink goes to the ipfs.io web gateway, and therefore ipfs.io can be compromised in all of the same ways bitaddress.org could be compromised: this is true. Canonical IPFS paths look like /ipfs/QmYz4b... (no hostname) and are accessed without using a gateway, but browsers do not yet support IPFS natively.

If you want to use IPFS without trusting a web gateway, you can already do so today! Follow the Getting Started guide and then install a browser extension like IPFS Gateway Redirect for Firefox or IPFS Station for Chrome, and IPFS gateway URLs (like the above) will be automatically redirected to your local IPFS node. This is easy to do, but if you want help setting this up please just email me and I'd be delighted to walk you through it: james@incoherency.co.uk.

The astute will also note that bugfixes or other updates to bitaddress.org will not be made available at that IPFS path: this is also true. This is a feature as much as it is a bug; it is simply a consequence of the fact that nobody can change the code. If you want to use an updated version of bitaddress.org, you need to publish that version on IPFS and distribute the new IPFS path. But only one person has to do this, and then everybody benefits. It's akin to shipping updates to any other non-auto-updating client-side software.

What I did

After Installing IPFS (extremely quick and simple, and no external dependencies), publishing bitaddress.org on IPFS went as follows:

$ git clone https://github.com/pointbiz/bitaddress.org
$ cp bitaddress.org/bitaddress.org.html bitaddress.org/index.html
$ ipfs add -r bitaddress.org/

(I copied bitaddress.org.html to index.html for sake of convenience; it's not strictly necessary but would make the URLs more cumbersome if we had to append /bitaddress.org.html all the time).

The last line of output from ipfs add was:

added QmYz4bkhtdkGRLFtago2hoNucrfUy5bHwrun8N8XJrrKWA bitaddress.org

This tells us the hash of the directory we just added. This is now available, immediately, everywhere with IPFS connectivity (which, thanks to public gateways like the one at ipfs.io, is everywhere on the web), at /ipfs/QmYz4bkhtdkGRLFtago2hoNucrfUy5bHwrun8N8XJrrKWA.

I also have a couple more IPFS nodes, so to maximise the availability (e.g. to avoid the situation where my laptop is the only node with the content, and is not online), I have pinned the hash on those nodes:

$ ipfs pin add QmYz4bkhtdkGRLFtago2hoNucrfUy5bHwrun8N8XJrrKWA

If you want to make sure it stays online even if I disappear, you can pin it too.

How you can verify that I did it correctly

The above is all well and good, but you really need to make sure that I published the real bitaddress.org content, and didn't insert any of my own modifications (or, at least, somebody needs to do it, and everybody else can trust him, or verify it themselves if they're not sure). You have 2 approaches:

1.) Duplicate what I did

Clone the git repo, checkout commit 72aefc0, copy bitaddress.org.html to index.html, and then add the whole directory (excluding .git/, but the default behaviour is to ignore hidden files anyway). If I didn't cheat, you should get the same hash at the end: QmYz4bkhtdkGRLFtago2hoNucrfUy5bHwrun8N8XJrrKWA

2.) Check that the content in IPFS matches the content in git

Alternatively, you can clone the git repo, checkout commit 72aefc0, and then download the content from IPFS:

$ ipfs get QmYz4bkhtdkGRLFtago2hoNucrfUy5bHwrun8N8XJrrKWA

The content will be downloaded to a directory called QmYz4bkhtdkGRLFtago2hoNucrfUy5bHwrun8N8XJrrKWA. You can then use diff, sha256sum, or any other tools you enjoy using, to look for differences between the git repo directory and the IPFS content directory.

Other Bitcoin-related tools

While I was at it, I also decided to publish stegoseed and Ian Coleman's BIP39 tool on IPFS.

bitaddress.org

IPFS path: /ipfs/QmYz4bkhtdkGRLFtago2hoNucrfUy5bHwrun8N8XJrrKWA
Web URL: https://bitaddress.org
Git repo: https://github.com/pointbiz/bitaddress.org
Git commit: 72aefc0

I copied bitaddress.org.html to index.html before adding the directory to IPFS.

stegoseed

IPFS path: /ipfs/QmSaJUuCesYDpxLbHrrKA3m2HjN4YcufhAtDH2achrY97z
Web URL: http://incoherency.co.uk/stegoseed/
Git repo: https://github.com/jes/stegoseed
Git commit: 24886cd

Didn't change any files as index.html already exists.

Ian Coleman's BIP39 tool

IPFS path: /ipfs/QmaF4DKh6nyYfrboYRvzbJarY9ntRUup2xPqs2DpbaoWnh
Web URL: https://iancoleman.github.io/bip39/
Git repo: https://github.com/iancoleman/bip39
Git commit: 0d11505

I copied bip39-standalone.html to index.html before adding the directory to IPFS.

Host your client-side applications on IPFS

If you have written any client-side applications, you can host them on IPFS in a matter of minutes and reap all of the benefits:

  • 1.) Nobody has to trust you
  • 2.) Nobody stands to gain anything from compromising you
  • 3.) You don't need your server to handle spikes in load - a spike in users accessing the content means a corresponding spike in the amount of nodes able to serve the content
  • 4.) You don't need to run a persistent server at all (but your content might disappear if you can't guarantee there is always at least one node hosting it - won't be a problem for popular content)

It's quick and easy. In fact, it's significantly easier to host content on IPFS than on a traditional website, and also comes with almost zero maintenance burden as you don't need to run a server. Just run ipfs add, and your content is online for all to see. If you don't already have some traditional hosting setup, you could consider going IPFS-only.

Where to learn more about IPFS

(Disclaimer: I'm absolutely nothing to do with the IPFS project, just a massive fanboy).

If you haven't done so already, follow the IPFS Getting Started guide, and then install a gateway-redirecting browser extension. The other IPFS documentation is also top quality.

The IRC channel #ipfs on Freenode is quite lively, lots of discussion happens on the ipfs github project, and there is a discussion board at discuss.ipfs.io.

Please email me if you have anything to say. I want to hear from you: james@incoherency.co.uk.

If you like my blog, please consider subscribing to the RSS feed or the mailing list:
or follow me on Twitter.

James Stanley - james@incoherency.co.uk | jesblogfnk2boep4.onion | /ipns/jes.xxx/ | [rss]