Search code examples
githubgithub-apipgpopenpgp

GitHub API OpenPGP key format


What is the format of the public_key field returned from GitHub REST API v3 for GPG Keys?

For example, the command curl -v -H "Accept: application/vnd.github.cryptographer-preview" https://api.github.com/users/DurandA/gpg_keys returns the following keys:

pub   dsa2048/403094DF 2017-09-03 [SC] [expires: 2018-09-03]
uid         [ultimate] Arnaud Durand <[email protected]>
sub   elg2048/A454F414 2017-09-03 [E] [expires: 2018-09-03]

According to the API doc:

The data returned in the public_key response field is not a GPG formatted key. When a user uploads a GPG key, it is parsed and the cryptographic public key is extracted and stored. This cryptographic key is what is returned by the APIs on this page. This key is not suitable to be used directly by programs like GPG.

Is it possible to use these keys from a CLI or programmatically?


Solution

  • The key returned is a bare (RSA, DSA, ...) key, which cannot be used by implementations of OpenPGP without "wrapping" it in a proper OpenPGP key packet again. I would not recommend to do so, why you should be able to construct the key packet again, you will have no chance in constructing binding signatures for subkeys and user IDs (this requires access to the private keys) and will not succeed and constructing something useful therefor.

    The "OpenPGP model" of sharing keys in communities is fetching a current copy from the key server network (including all current certifications and revocations) instead of relying on possibly outdated versions in "third-party-locations" like GitHub. This is possible by fingerprints and key IDs that (more or less uniquely, see below) address specific keys -- do not search for mail addresses, everybody can create keys with arbitrary user IDs and keyservers do not perform any validation.

    Instead, have another look at the APIs output, which returns keyid objects for all keys (some for subkeys):

    [
      {
        "id": 3,
        "primary_key_id": null,
        "key_id": "3262EFF25BA0D270",
        "public_key": "xsBNBFayYZ...",
        "emails": [
          {
            "email": "[email protected]",
            "verified": true
          }
        ],
        [snip]
      }
    ]
    

    To use such a key ID, run gpg --recv-keys <key-id>. And drop GitHub a note to follow best practices and include the full fingerprint:

    These 64-bit hex values (3262EFF25BA0D270 in this example) are long key IDs. While any programmatic references to keys should always include the key's fingerprint, not abbreviated key IDs, at least they do not provide short key IDs that heavily suffer under collision attacks.