2020-05-08 Replacing Keybase

OK, so Keybase was bought by Zoom and I deleted my Keybase identity. @wiktor@metacode.biz said he had a decentralized alternative.

You can find a simple description here: OpenPGP Proofs.

Here’s how I understand it:

  1. on an online service, mention your fingerprint in a particular way
  2. add that link to your key in a particular way
  3. potentially use some software to verify it, or do it manually

Let’s do this.

Determine my fingerprint:

alex@melanobombus:~$ gpg --fingerprint alex@gnu.org
pub   rsa8192 2015-03-01 [SC] [expires: 2021-05-07]
      DF94 46EB 7B78 4638 7CCC  018B C78C A29B ACEC FEAE
uid           [ unknown] Alex Schroeder <alex@gnu.org>
uid           [ unknown] Alex Schroeder <kensanata@gmail.com>
uid           [ unknown] [jpeg image of size 5665]
uid           [ unknown] Alex Schroeder <alex@alexschroeder.ch>
sub   elg3072 2019-01-20 [E] [expires: 2021-01-30]

(and many other expired and revoked keys)

The fingerprint in question, with no spaces and converted to lower case: df9446eb7b7846387ccc018bc78ca29bacecfeae

Make sure you’re using the keys.openpgp.org keyserver. For a modern GPG installation, your ~/.gnupg/gpg.conf file should have this line:

keyserver hkps://keys.openpgp.org

Send your key to keyserver:

alex@melanobombus:~$ gpg --send-key df9446eb7b7846387ccc018bc78ca29bacecfeae
gpg: sending key C78CA29BACECFEAE to hkps://keys.openpgp.org

GitHub

I’m going to create a proof for my GitHub account.

Create a new Gist. Use openpgp.md as the filename. Write whatever but somewhere in that text, use the String Verifying my OpenPGP key: openpgp4fpr:{FINGERPRINT}. Here’s the Gist I created.

Now, edit your key, adding a notation pointing to the Gist, save it, and send the key to the keyservers.

alex@melanobombus:~$ gpg --edit-key df9446eb7b7846387ccc018bc78ca29bacecfeae
Secret key is available.

sec  rsa8192/C78CA29BACECFEAE
     created: 2015-03-01  expires: 2021-05-07  usage: SC  
ssb  rsa4096/0C8706F1F6881931
     created: 2015-03-01  expired: 2019-02-28  usage: S   
ssb  rsa8192/11C583644529A45C
     created: 2015-03-01  expired: 2019-02-28  usage: E   
ssb  elg3072/DE6718E639D2D11F
     created: 2019-01-20  expires: 2021-01-30  usage: E   
[ unknown] (1). Alex Schroeder <alex@gnu.org>
[ unknown] (2)  Alex Schroeder <kensanata@gmail.com>
[ unknown] (3)  [jpeg image of size 5665]
[ unknown] (4)  Alex Schroeder <alex@alexschroeder.ch>

gpg> notation
Enter the notation: proof@metacode.biz=https://gist.github.com/kensanata/ffb8ecad8d48c9091ad63fb767534340
No notations on user ID "Alex Schroeder <alex@gnu.org>"
Adding notation: proof@metacode.biz=https://gist.github.com/kensanata/ffb8ecad8d48c9091ad63fb767534340
No notations on user ID "Alex Schroeder <kensanata@gmail.com>"
Adding notation: proof@metacode.biz=https://gist.github.com/kensanata/ffb8ecad8d48c9091ad63fb767534340
No notations on user ID "[jpeg image of size 5665]"
Adding notation: proof@metacode.biz=https://gist.github.com/kensanata/ffb8ecad8d48c9091ad63fb767534340
No notations on user ID "Alex Schroeder <alex@alexschroeder.ch>"
Adding notation: proof@metacode.biz=https://gist.github.com/kensanata/ffb8ecad8d48c9091ad63fb767534340

sec  rsa8192/C78CA29BACECFEAE
     created: 2015-03-01  expires: 2021-05-07  usage: SC  
ssb  rsa4096/0C8706F1F6881931
     created: 2015-03-01  expired: 2019-02-28  usage: S   
ssb  rsa8192/11C583644529A45C
     created: 2015-03-01  expired: 2019-02-28  usage: E   
ssb  elg3072/DE6718E639D2D11F
     created: 2019-01-20  expires: 2021-01-30  usage: E   
[ unknown] (1). Alex Schroeder <alex@gnu.org>
[ unknown] (2)  Alex Schroeder <kensanata@gmail.com>
[ unknown] (3)  [jpeg image of size 5665]
[ unknown] (4)  Alex Schroeder <alex@alexschroeder.ch>

gpg> save
alex@melanobombus:~$ gpg --send-key df9446eb7b7846387ccc018bc78ca29bacecfeae
gpg: sending key C78CA29BACECFEAE to hkps://keys.openpgp.org

If you’re wondering about the proof@metacode.biz key used, there’s an explanation in the FAQ:

This e-mail-like string is actually notation key. RFC 4880 specifies this kind of format as a way to namespace custom notations. You need to create notations under the domain that you own to avoid conflicts. I used my own domain for this protocol. Ideally the notation key would be just proof. Using this kind of keys (without @ namespacing) is only allowed for IETF-approved extensions though (I did not approach them).

So, one day it might be just proof. But we need to agree on a key for tools to work and so proof@metacode.biz is as good as any.

Here’s how to manually verify the key:

alex@melanobombus:~$ gpg --list-options show-notations --list-sigs df9446eb7b7846387ccc018bc78ca29bacecfeae | grep proof
   Signature notation: proof@metacode.biz=https://gist.github.com/kensanata/ffb8ecad8d48c9091ad63fb767534340
   Signature notation: proof@metacode.biz=https://gist.github.com/kensanata/ffb8ecad8d48c9091ad63fb767534340
   Signature notation: proof@metacode.biz=https://gist.github.com/kensanata/ffb8ecad8d48c9091ad63fb767534340
   Signature notation: proof@metacode.biz=https://gist.github.com/kensanata/ffb8ecad8d48c9091ad63fb767534340

Visit the URL and check that the fingerprint mentioned is in fact the fingerprint you used in your query. If so, verified! ✔

And here’s how to do it automatically.

You can host the web app somewhere, or use Wiktor’s installation, passing along the fingerprint in question as part of the URL:

Click for the live version

This is soooo beautiful! 😍

Thanks, Wiktor!

That’s all I ever wanted Keybase to do for me. And now there’s a way to do this, but decentralized. This is awesome.

Mastodon

I’m adding my fingerprint as one of the four profile metadata elements available to me on Mastodon, followed by:

gpg --edit-key df9446eb7b7846387ccc018bc78ca29bacecfeae
notation
proof@metacode.biz=https://octodon.social/@kensanata
save
gpg --send-key df9446eb7b7846387ccc018bc78ca29bacecfeae

Reddit

I’m posting the same text I used above to Reddit, followed by:

gpg --edit-key df9446eb7b7846387ccc018bc78ca29bacecfeae
notation
proof@metacode.biz=https://www.reddit.com/user/kensanata/comments/gfzrkn/proof_of_identity_decentralized/
save
gpg --send-key df9446eb7b7846387ccc018bc78ca29bacecfeae

Email

Remember, we’re using keys.openpgp.org. They don’t publish email addresses unless you’ve agreed to it. That means a confirmation mail per email. We need to do the following for every email address we want to make available:

  1. submit it to keys.openpgp.org
  2. get the confirmation link
  3. click the link to request a confirmation mail
  4. click the link in the confirmation mail

In order to get started, you have to submit your key without using --send-key. I know, it’s weird. But that’s the way to get the confirmation link:

alex@melanobombus:~$ gpg --export alex@alexschroeder.ch | curl -T - https://keys.openpgp.org
Key successfully uploaded. Proceed with verification here:
https://keys.openpgp.org/upload/...

Click the link to request the confirmation mail, wait for the confirmation mail, click the link in the confirmation mail, and now your address is listed!

Verify this by search for your email addresses on keys.openpgp.org.

Do this for every email address you want to see listed (possibly all of them).

Searching for emails

Remember how I said above that you can pass the fingerprint of a key to the web app, like this:

https://alexschroeder.ch/openpgp/#0xdf9446eb7b7846387ccc018bc78ca29bacecfeae

If you’re self-hosting your email, there’s the option of allowing an email address instead of the fingerprint, using a Web Key Directory. One day, tools will be able to handle encryption without having to know about fingerprints. 🙂 The same is true for the web app:

https://alexschroeder.ch/openpgp/#alex@alexschroeder.ch

If you have control over a domain but don’t use it for email, there’s still a way to get this to work using a subdomain under your control and keys.openpgp.org but I’m not going to cover that. I would have to do that for my GNU and GMail addresses. The following section just covers the email address I receive under my own domain, alex@alexschroeder.ch.

In order for this to work, we need to do the following:

  1. export our key
  2. rename it so it matches the hash of the local part (alex in my case)
  3. serve it from the same domain from a well-known location

Let’s determine the hash using --with-wkd:

alex@melanobombus:~$ gpg --list-keys --with-wkd alex@alexschroeder.ch
pub   rsa8192 2015-03-01 [SC] [expires: 2021-05-07]
      DF9446EB7B7846387CCC018BC78CA29BACECFEAE
uid           [ unknown] Alex Schroeder <alex@gnu.org>
              cddpr77ezsy7h967hgjydxhhmnt76n8w@gnu.org
uid           [ unknown] Alex Schroeder <kensanata@gmail.com>
              cps1z1ccmfq5zj33zg7z3s49sehtefwz@gmail.com
uid           [ unknown] [jpeg image of size 5665]
uid           [ unknown] Alex Schroeder <alex@alexschroeder.ch>
              cddpr77ezsy7h967hgjydxhhmnt76n8w@alexschroeder.ch
sub   elg3072 2019-01-20 [E] [expires: 2021-01-30]

Thus, I need to export my public key using gpg --export alex@alexschroeder.ch > cddpr77ezsy7h967hgjydxhhmnt76n8w and serve it from https://alexschroeder.ch/.well-known/openpgpkey/hu/.

In addition to that, I created a .htaccess file in my openpgpkey directory containing the following:

Options -Indexes
Header set Access-Control-Allow-Origin "*"

The first line disables the listing of directory contents and the second line sets the Access-Control-Allow-Origin such that this information may be retrieved from elsewhere, not just my own server.

You can test the setup using Wiktor’s Web Key Directory page.

Sadly, when testing it from the command line, it doesn’t work as expected. Here I am, using --locate-keys from a different account where I don’t have access to my key:

alex@sibirocobombus:~$ gpg --locate-keys alex@alexschroeder.ch
gpg: error retrieving 'alex@alexschroeder.ch' via WKD: No data
gpg: error reading key: No data

Oops! 😭

Something’s missing. But what is it?

Self Hosting the Application

On your webserver, create a directory called openpgp with a copy of the files in the openpgp-proofs repository. The directory I’m using is accessible from the web as https://alexschroeder.ch/openpgp. This is important later because the script expects proofs.json at this location.

Run npm install --production in this directory. You’ll get a bunch of dependencies installed into the node_modules directory.

If you’re like me and you’ve set a Content Security Policy, you need to allow clients to make requests to the keyserver and to all the sites hosting the proofs. Thus, we really need to relax our CSP, unfortunately. But there’s no way around it!

In my .htaccess file, I put:

DirectoryIndex index.html
Header set Content-Security-Policy "default-src https: data:; object-src 'none'; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'"

And here it is! 😀

Note that my primary browser is Firefox which blocks a bunch of requests so that the proofs cannot be fetched. When I use Chromium, which is less paranoid, all my proofs are verified. 👍

Tags:

Comments

DeletedPage


Please make sure you contribute only your own work, or work licensed under the GNU Free Documentation License. Note: in order to facilitate peer review and fight vandalism, we will store your IP number for a number of days. See Privacy Policy for more information. See Info for text formatting rules. You can edit the comment page if you need to fix typos. You can subscribe to new comments by email without leaving a comment.

To save this page you must answer this question:

Please say HELLO.