PGP with YubiKey & Keybase & Protonmail

TABLE OF CONTENTS


Intro to YubiKey and generating GPG keys

It has been a good few months since I started playing with and using YubiKey 5ci.
So far I haven’t really used it for anything more serious, at least not until I learn enough about its capabilities, as well as how to use it together with gpg suite.

YubiKey 5Ci truly is the first of its kind.
Of all the features you can read about on the product page I would just mention these:

  • Function: WebAuthn, FIDO2 CTAP1, FIDO2 CTAP2, Universal 2nd Factor (U2F), Smart card (PIV-compatible), Yubico OTP, OATH – HOTP (Event), OATH – TOTP (Time), Open PGP, Secure Static Password
  • Cryptographic Specifications: RSA 2048, RSA 4096 (PGP), ECC p256, ECC p384
  • Certifications: FIDO 2 Certified, FIDO Universal 2nd Factor (U2F) Certified
  • Device Type: FIDO HID Device, CCID Smart Card, HID Keyboard

It is also worth mentioning that it has good support from password managers.
Basically, you can use it as 2nd factor authentication device in two ways:

  1. By using it as virtual MFA device. For this to work you need the device plugged into one of your mobile/desktop (physical) devices and Yubico Authenticator app/client for one of the supported OSes.

  2. By using it as FIDO U2F device. For those that are new to this, here is what it means:

    U2F is an open authentication standard that enables internet users to securely access any number of online services with one single security key instantly and with no drivers or client software needed.

    You can read more about this feature on the product page.
    Basically the device comes equipped with two pins (one on each side) that you need to press when prompted for 2nd factor key from services that support this standard. On the press of those keys, device generates series of keystrokes that are verified by service provider, in similar fashion how OTP tokens are generated in the 1st option above.

It may have caught your attention but if it did not - this device also can behave as a Smart Card and offers Open PGP functionality. What this means is that you can use it to manage your GPG keys in multiple ways. And that is exactly what I want to focus on in this post, with emphasis on my use-cases:

  1. Using GPG keys managed by YubiKey with Keybase
  2. Using GPG keys managed by YubiKey with ProtonMail
  3. IDEALLY - Using just single GPG key managed by YubiKey for both Keybase and ProtonMail

First and probably most important thing to know (which you could guess, I didn’t know when I started experimenting) is that with posession of security key (YubiKey), users have two strategies how to manage GPG keys:

  1. Generating Keys externally from the YubiKey
  2. Generating Your PGP Key directly on Your YubiKey

Both of the above methods have pros and cons:

Pros:

  • 1st method provides opportunity to backup GPG keys elsewhere
  • 2nd method (generating the PGP on the YubiKey) ensures that malware can never steal your PGP private key

Cons:

  • 1st method - it is strongly recommended that you to generate keys on an offline system
  • 2nd method - it means that the key can not be backed up so if your YubiKey is lost or damaged the PGP key is irrecoverable

However, of the two methods above, the first one is strongly recommended (by YubiKey) because 1st method provides opportunity of “safely” backup GPG keys (in sume durable form - either paper or other electronic form), at least according to the official article Using Your YubiKey with OpenPGP. You can find more details about proceedure for generating GPG keys for both strategies on that page.

As far as my keys are concerned, I have followed another (by now very famous guide) at drduh/YubiKey-Guide.

The process is pretty straightforward and eventually I ended up with 1 master key and 3 subkeys (one for signing, one for encryption and one for authentication):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> gpg -K --keyid-format LONG

/Users/amer/.gnupg/pubring.kbx
------------------------------
sec# rsa4096/F2036890CCE43A6E 2020-12-15 [C]
Key fingerprint = 87DE DBA3 6B74 59EB A9DB 60D4 F203 6890 CCE4 3A6E
uid [ultimate] Amer Zec <amer.zec@pm.me>
uid [ultimate] Amer Zec <azec.pdx@pm.me>
uid [ultimate] Amer Zec <amerzec@gmail.com>
uid [ultimate] Amer Zec <amer.zec@skyward.io>
uid [ultimate] Amer Zec <azec.pdx@protonmail.com>
ssb> rsa4096/C7C4CE019E24528B 2020-12-15 [S] [expires: 2031-05-04]
ssb> rsa4096/337469C332E23BC2 2020-12-15 [E] [expires: 2031-05-04]
ssb> rsa4096/AF7288986C0C508B 2020-12-15 [A] [expires: 2031-05-04]

Next, I wanted to explore how can I use this key with Keybase.

Using GPG keys (managed by YubiKey) with Keybase

Keybase comes with variety of options for PGP in its CLI subcommand keybase pgp [OPTIONS]. The ones most relevant for our topic here are:

1
2
3
4
select	Select a key from GnuPG as your own and register the public half with Keybase
import Import a PGP key into keybase
drop Drop Keybase's use of a PGP key
list List the active PGP keys in your account.

If you had any previously generated (and/or managed by Keybase) GPG keys, I recommend that you use drop option to drop them. This was certainly my case, as I was only interested in adding to the Keybase my public GPG key, specifically the one managed by YubiKey, so that other users on this network can use it to encrypt messages to me via Keybase Chat.

Now to the hard part. There are two very similar but somewhat confusing ways to add your GPG key to Keybase. Using select or using import subcommand listed above. In this step, it really depends what you want to do.
As I said earlier, my interest WAS NOT to have Keybase keyring managing any secret/private part of my GPG keys. So I had to read carefully what each of these subcommands does. And for posterity, here is the the gist of each:

  • The import subcommand

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    USAGE:
    keybase pgp import [command options]

    DESCRIPTION:
    "keybase pgp import" imports a PGP secret key for use with Keybase.
    It accepts that secret key via file (with the "--infile" flag) or
    otherwise via standard input. The secret key is used to sign the
    public PGP key into the user's Keybase sigchain. The secret key
    is also imported into the local Keybase keyring and encrypted with
    the local key security protocol.

    If (and only if) the "--push-secret" flag is specified, this command
    pushes the PGP secret key to the Keybase server, encrypted with the
    user's passphrase. The server, in this case, could theoretically
    recover the PGP secret key by cracking the user's passphrase.

    OPTIONS:
    -i, --infile Specify an infile (stdin by default).
    --push-secret Push an encrypted copy of the secret key to the server.

    As I have already stated twice, my case was not to import secret key to local Keybase keyring and neither was it to push secret key to Keybase server.
    So I completely skipped this subcommand.

  • The select subcommand

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    USAGE:
    keybase pgp select [command options] [key query]

    DESCRIPTION:
    "keybase pgp select" looks at the local GnuPG keychain for all
    available secret keys. It then makes those keys available for use with keybase.
    The steps involved are: (1a) sign a signature chain link with the selected PGP
    key and the existing device key; (1b) push this signature and the public PGP
    key to the server; and if "--import" flag is passed: (2a) copy the PGP secret half
    into your local Keybase keyring; and (2b) encrypt this secret key with Keybase's
    local key security mechanism.

    By default, Keybase suggests only one PGP public key, but if you want to,
    you can supply the "--multi" flag to override this restriction. If you
    want your secret key imported into the local Keybase keyring, then use
    the "--import" flag. Importing your secret key to Keybase keyring makes
    it possible to use Keybase PGP commands like "pgp decrypt" or "pgp sign".

    If you don't want to publish signature chain link to Keybase servers, use
    "--no-publish" flag. It's only valid when both "--no-publish" and "--import"
    flags are used.

    This operation will never push your secret key, encrypted or otherwise,
    to the Keybase server.

    OPTIONS:
    --multi Allow multiple PGP keys.
    --import Import private key to the local Keybase keyring.
    --no-publish Only import to Keybase keyring, do not publish on user profile.

    As described, this command provides a way of selecting multiple GPG keys from local GPG keyring and then making them available for use with Keybase. So basically, this is all I needed (minus all the fancy stuff).

So to finalize this section, I have done following to make my public GPG key available to Keybase:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> keybase pgp select --multi

You are selecting a PGP key from your local GnuPG keychain, and
will publish a statement signed with this key to make it part of
your Keybase.io identity.

Note that GnuPG will prompt you to perform this signature.

You can also import the secret key to *local*, *encrypted* Keybase
keyring, enabling decryption and signing with the Keybase client.
To do that, use "--import" flag.

Learn more: keybase pgp help select

# Algo Key Id Created UserId
= ==== ====== ======= ======
1 4096R F2036890CCE43A6E Amer Zec <amer.zec@pm.me>, Amer Zec <azec.pdx@pm.me>, Amer Zec <amerzec@gmail.com>, Amer Zec <amer.zec@skyward.io>, Amer Zec <azec.pdx@protonmail.com>
Choose a key:

After selecting the only option available (1) my key showed up as verified and published on Keybase 0xF2036890CCE43A6E. Notice that I did not pass --import flag to the above command, as I am not interested in the Keybase CLI features such as keybase pgp decrypt and keybase pgp sign.

Next, I wanted to explore how can I use this same GPG key with ProtonMail.

Using GPG keys (managed by YubiKey) with ProtonMail

Now, in the interest of saving you time - I will state it upfront, this is actually not possible. If you are interested in knowing more about why, read on.

So one thing about ProtonMail is that their UI provides users with opportunity to generate new PGP keys. This is all well described in their How to use PGP article.
And for quite some time, I have had separate keys that vere completely managed by ProtonMail. By managed, I mean, that keys were generated on ProtonMail and never ever exported elsewhere to any external system. While ProtonMail allows exporting both public and private GPG keys generated by their UI, I never had interest in doing so.

Also, I didn’t have a need to generate ProtonMail GPG keys externally and import them (another ProtonMail feature), until now. I was on the happy path following these steps:

  1. I have analyzed keys (by importing them to local GPG keyring) that were managed by ProtonMail to see what capabilities they have. I noted that they generate 1 subkey which has both [SC] capabilities. I also noted that this is not the case with any of my subkeys generated with YubiKey and started wondering if this will be causing any issues when I try to import YubiKey-managed keys.
  2. I completely deleted my GPG keys managed by ProtonMail from their UI attached to one of my e-mail identities of interest. I also deleted them from the local GPG keyring.
  3. (please do this with caution), I have obtained my YubiKeys backup, and tried to import subkeys private key + public key to ProtonMail. Everything was smooth until it prompted me for private key passphrase. However with 100% certainty that I am entering correct passphrase, it kept re-prompting me endlessly to enter it again. At this point I knew there is something wrong and decided to stop here.

After being blocked on step 3. I have decided to reach out to ProtonMail support and describe my case. Here is the gist of my ask and their follow-up.

me:

Timestamp: 1620182869

Hi there,

I am trying to consolidate my GPG subkeys managed with YubiKey and my GPG keys imported in ProtonMail. Originally I was generating private/public key from within ProtonMail - one for each of my ProtonMail identities and when I export them and import them to my GPG ring they show following:

pub rsa4096 2019-03-14 [SC]
766B78E832154AD500656D3B289A688B26C7CA3A
uid [ unknown] amer.zec@pm.me <amer.zec@pm.me>
sub rsa4096 2019-03-14 [E]

pub rsa4096 2021-04-25 [SC]
9C2BEC2FB2A1289237BCDA0349AA76F7ECE2D91A
uid [ unknown] azec.pdx@pm.me <azec.pdx@pm.me>
sub rsa4096 2021-04-25 [E]

However, since I started using YubiKey I have this setup:
1 master key with C capability
1 subkey with S capability
1 subkey with E capability
1 subkey with A capability

and all my ProtonMail and other e-mail identities are added to the master key.

So I am curious if there is a way for me to discard above keys that originated by ProtonMail and import some combination of subkeys that I manage with YubiKey? If so, would the capabilities of my existing keys be sufficient, or I would have to create additional subkeys just for ProtonMail use?

Thanks!

ProtonMail support:

Hello,

Thank you for contacting ProtonMail support.

Unfortunately, importing subkeys without the master key is not supported. In the GPG documentation, you can see that "this is a GNU extension to OpenPGP and other implementations cannot be expected to successfully import such a key."
https://www.gnupg.org/documentation/manpage.html

Our documentation on using PGP can be found in this article:
https://protonmail.com/support/knowledge-base/how-to-use-pgp/

Feel free to get back to us with any additional questions or concerns. Our team remains available if needed. 
Kind regards,
Ivana

Customer Support
ProtonMail

So while the quick follow up kicked in with joy once I saw the e-mail, it was pretty disappointing to learn that ProtonMail doesn’t support importing subkeys. And for me, importing my master secret key (after moving it to YubiKey secure card) was not an option.

As an alternative, I have decided to use separate ProtonMail managed pair of GPG keys, as listed below (links lead to public key hosted on my website):

So that is all for now. In the next post, I will try to focus on:

  1. Using GPG keys on YubiKey for signing git commits (and making sure they are verified on GitHub)
  2. Using GPG keys on YubiKey for generating secure SSH keys for GitHub authentication, with private key material never leaving YubiKey (not being on your local machine). This is relatively new feature as of May 10th 2021 and I have been already using it for a day and I am very excited to write about it.

I hope you enjoyed the read and please stop by soon!