Distributed social networks – tools that give you all the social and political benefits of the siloed networks (Google+, Facebook, etc), but without being a massive honey pot for surveillance and data mining, are, in my view, the way we should be heading.

In this model, public posts are easy (that’s just the web), but limiting posts so that they can only be seen by a limited number of your friends is somewhat harder. On Elgg, and similar systems, the standard solution was to make everyone create an account, and profile, on your node. This is, to a large extent, the traditional approach, but basically ends up with you having multiple profiles around the internet (with multiple passwords to remember) which are, crucially, controlled by a third party.

This is a bad thing, and in the post Snowden world, a downright dangerous thing.

I’ve previously discussed a possible approach to providing distributed signon using OpenPGP keys as identity mechanism, and I’ve finally got around to fleshing this out, and building a prototype, now that distributed friending is in Idno/Known core.

Protocol overview

  • Two user profiles, Alice and Bob
  • Alice and Bob generate, or otherwise associate, a PGP key pair with their users (for the most part, only public keys are used in this. You only need to store the private key on the server if you’re automating the process of signing in, and if you can store your private key in your browser, there is eventually no need to store private keys on the server).
  • Alice adds Bob as a friend, and Alice’s site visits Bob’s profile for his public key (see “Public key discovery” below)
  • Rinse, repeat, for Clare, Dave, Emma, Fred, etc…
  • Alice writes a post, and only wants Bob to see it. She lists Bob’s profile URL as an approved viewer.
  • Bob visits the private post, and identifies himself by signing his profile URL with his key, and then POSTing the ascii armoured signature as signature to the post URL.
  • Alice verifies the signature, and confirms that the key’s fingerprint belongs to Bob’s key, and if so, lets Bob see the post.

Public key discovery

Bob makes his public key available by putting it on his web server, and making it easily discoverable to Alice in one or more of the following ways:

  1. Via a HTTP Link header, with a rel of “key”, e.g. Link: https://example.com/bob/pubkey.asc; rel="key"
  2. Via a META tag in the HTTP header, e.g. <meta href="https://example.com/bob/pubkey.asc" />
  3. Via an anchor tag within the page body of rel=”key”, e.g. <a href="https://example.com/bob/pubkey.asc" rel="key">My Key</a>
  4. By pasting the key into the body of the page, and giving it a class of “key”, e.g.

<pre class="key">
-----BEGIN PGP PUBLIC KEY BLOCK-----
....
-----END PGP PUBLIC KEY BLOCK-----
</pre>

Identifying Bob

When Bob wants to see the post that Alice has made, he identifies himself by making a POST request to that page, containing a signed URL of his profile. Alice then verifies the profile URL against those she as allowed access, and verifies that the signature is both correct and that the fingerprint belongs to Bob’s key.

Alice may want to store these access details in a session so she can give Bob access to other resources (logging Bob in, in effect), but this is not strictly necessary.

Other methods are available…

So, why not use OAuth, or signed HTTP requests?

Well first of all, all these authentication methods are not mutually exclusive, so there’s no reason why you can’t use multiple techniques.

Second, we’re using very standard tools (GPG, POST requests, etc), and standard formats, bolted together. Meaning, among other things, although this example (and the Idno implementation) uses a website to do the signing in, this isn’t really required. You can sign in and see a private post, just as easily, using curl and gpg from the command line, if you so require.

Finally, this is entirely distributed, and unlike some implementations of Oauth, or even things like IndieAuth, it requires no central authority to vouch for you. Update:Aaron points out that the latest versions of Indieauth don’t require a central authority.

Idno reference implementation

I have written a plugin that implements this protocol for Idno. In addition to the basic spec, the Idno plugin has the following enhancements, which you may want to consider as well.

Firstly, it uses OpenPGP.js to generate the keypair on the client machine. This preserves server entropy, making it better for hosted environments.

Secondly, the plugin provides you with a bookmarklet, which makes signing in to a compatible site nothing more than a button click.

Please kick both the Idno implementation and the overall spec about, and let me know what you think!

» Visit the project on Github...

Steganography is the term given to the art of hiding a message, for example in a photograph, in such a way that unless you know it’s there you wouldn’t suspect it was there.

While this is, to some extent, security through obscurity, it can be handy in some situations. Since a cursory look at the files will show something relatively innocuous (holiday snaps for example), an attacker may not notice the presence of the hidden data, and so move on without even attempting to break it.

There are many sophisticated technologies for doing this, however you can do a basic version using fairly standard unix tools.

Preparing your files

The first step is to encrypt your data.

To some extent, this is optional, however should your ruse be rumbled you can be sure that your precious data doesn’t fall into the wrong hands.

gpg -e -u "you@example.com" -r "them@example.com" businessplan.doc

Then, you compress the output using Zip. This is important, since unzip will ignore anything it doesn’t recognise as zipped data, which we’ll get onto later.

zip businessplan.zip businessplan.doc.gpg

Hiding your file

Hiding your file in an image is relatively straightforward.

cat photo.jpg businessplan.zip > myholiday.jpg

What’s happening here is that we’ve combined a photo and your encrypted zip file together into one file (order is important). Your image viewers will only see the first image file, and anyone looking at the directory will just see a (somewhat large) jpeg. If thumbnails are enabled you’ll just see the contents of photo.jpg.

Retrieving your file

To retrieve your file, all your recipient needs to do is run unzip the image file. Unzip will skip over the jpg content with a warning, and then reveal the hidden file. They then need to unencrypted it using their secret key.

unzip myholiday.jpg
gpg -d businessplan.doc.gpg > businessplan.doc

In conclusion

This technique will allow you to hide an encrypted file in a jpeg image, which affords you a certain amount of extra protection. Unless you know a particular image contains encrypted data (or suspect it might and look a little harder) then chances are the presence of the encrypted data won’t be discovered. However, this technique is probably pretty easy to spot if an attacker is looking for it, or performing any kind of data analysis on the file (or even looking at the file size, which could be a give away depending on how much data you’re hiding).

If you are a journalist carrying evidence of war crimes or mass surveillance programs to Brazil, you are likely facing some highly skilled adversaries, so this technique is probably not suitable. But, if you’re a business person who wants to take your new business plan securely across a border without the hassle of possibly being detained and forced to decrypt the file, then this might be more useful.

In any case, I thought it was pretty cool, and I thought I’d share.