iTranslated by AI
Retrieving OpenPGP Public Keys Registered on GitHub
GitHub allows you to register OpenPGP public keys to verify digital signatures when committing or tagging, and you can retrieve these registered OpenPGP public keys arbitrarily using the REST API.
For example, the information for the public keys I have registered can be retrieved like this[1].
$ curl -s https://api.github.com/users/spiegel-im-spiegel/gpg_keys
[
{
"id": 1043333,
"primary_key_id": null,
"key_id": "B4DA3BAE7E20B81C",
"raw_key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\n...\r\n-----END PGP PUBLIC KEY BLOCK-----\r\n",
"public_key": "...",
"emails": [
{
"email": "spiegel.im.spiegel...",
"verified": true
}
],
"subkeys": [
{
"id": 1043334,
"primary_key_id": 1043333,
"key_id": "4308C4946F760D3C",
"raw_key": null,
"public_key": "...",
"emails": [
],
"subkeys": [
],
"can_sign": false,
"can_encrypt_comms": true,
"can_encrypt_storage": true,
"can_certify": false,
"created_at": "2020-10-13T22:07:23.000Z",
"expires_at": null
}
],
"can_sign": true,
"can_encrypt_comms": false,
"can_encrypt_storage": false,
"can_certify": true,
"created_at": "2020-10-13T22:07:23.000Z",
"expires_at": null
}
]
Please note that I have omitted some parts with ....
Since multiple public keys can be registered, the data is returned in an array structure. For instance, if you want to extract the first key, you can use the jq command:
$ curl -s https://api.github.com/users/spiegel-im-spiegel/gpg_keys | jq .[0]
If you already know the Key ID, you can do something like this:
$ curl -s https://api.github.com/users/spiegel-im-spiegel/gpg_keys | jq '.[]|select(.key_id=="B4DA3BAE7E20B81C")'
jq is incredibly convenient!
Within the retrieved information, the content of the raw_key field is the actual OpenPGP public key data registered on GitHub. To extract this, you can use jq with the -r option like this:
$ curl -s https://api.github.com/users/spiegel-im-spiegel/gpg_keys | jq -r '.[]|select(.key_id=="B4DA3BAE7E20B81C")|.raw_key'
-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----
This OpenPGP public key data can be imported directly into GnuPG and similar tools.
$ curl -s https://api.github.com/users/spiegel-im-spiegel/gpg_keys | jq -r '.[]|select(.key_id=="B4DA3BAE7E20B81C")|.raw_key' | gpg --import
It seems that for some registered public keys, the raw_key field might be null (perhaps for older registrations?). In this case, it cannot be retrieved as OpenPGP public key data, but you can still extract only the public key packet from the public_key field.
However, since it is BASE64 encoded, you will need to decode it into binary data using commands like base64 or openssl. Furthermore, you can visualize the extracted public key packet using my own tool, gpgpdump.
$ curl -s https://api.github.com/users/spiegel-im-spiegel/gpg_keys | jq -r '.[]|select(.key_id=="B4DA3BAE7E20B81C")|.public_key' | base64 -d | gpgpdump -u
Public-Key Packet (tag 6) (1198 bytes)
Version: 4 (current)
Public key creation time: 2013-04-28T10:29:43Z
Public-key Algorithm: DSA (Digital Signature Algorithm) (pub 17)
DSA p (3072 bits)
DSA q (q is a prime divisor of p-1) (256 bits)
DSA g (3070 bits)
DSA y (= g^x mod p where x is secret) (3067 bits)
Please note that a public key packet alone cannot be used as an OpenPGP public key[2]. If the raw_key field is missing but you still want to obtain the OpenPGP public key, you can extract the list of key IDs like this:
$ curl -s https://api.github.com/users/spiegel-im-spiegel/gpg_keys | jq -r .[].key_id
B4DA3BAE7E20B81C
Then, you would have to import it into GnuPG or similar tools from a key server as follows:
$ gpg --recv-keys B4DA3BAE7E20B81C
[Update 2020-10-14]
I was informed in the comments (thanks for the info!) that adding .gpg to the end of your user profile URL allows you to retrieve the OpenPGP public key data. In my case:
$ curl -s https://github.com/spiegel-im-spiegel.gpg
-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----
You can retrieve it this way. So you can either do:
$ curl -s https://github.com/spiegel-im-spiegel.gpg | gpg --import
or directly import it into GnuPG using:
$ gpg --fetch-key https://github.com/spiegel-im-spiegel.gpg
By the way, if multiple public keys are registered, all key data will be retrieved in a concatenated state. Conversely, for a user who hasn't registered any public keys, it will look something like this:
$ curl -s https://github.com/nokeyuser.gpg
-----BEGIN PGP PUBLIC KEY BLOCK-----
Note: This user hasn't uploaded any GPG keys.
=twTO
-----END PGP PUBLIC KEY BLOCK-----
[Update 2020-11-23]
I have updated my tool gpgpdump to be able to extract and visualize OpenPGP public keys registered on GitHub.
For example, if you find a signature like this on GitHub:
You can view the contents of the public key with the following command line:
$ gpgpdump github spiegel-im-spiegel --keyid B4DA3BAE7E20B81C -u
Public-Key Packet (tag 6) (1198 bytes)
Version: 4 (current)
Public key creation time: 2013-04-28T10:29:43Z
Public-key Algorithm: DSA (Digital Signature Algorithm) (pub 17)
DSA p (3072 bits)
DSA q (q is a prime divisor of p-1) (256 bits)
DSA g (3070 bits)
DSA y (= g^x mod p where x is secret) (3067 bits)
...
For details, please check the following article:
References
- Signing with OpenPGP in Git Commit — OpenPGP Implementation | text.Baldanders.info
- Summary of how to use jq
- GnuPG Cheat Sheet (Quick Version)
- Visualizing OpenPGP packets with gpgpdump — Release Information | text.Baldanders.info
-
When accessing the GitHub REST API using the curl command, it is technically correct to include the
-H "Accept: application/vnd.github.v3+json"option, but it seems to work fine without it for now. I will omit the GraphQL API this time. ↩︎ -
An OpenPGP public key consists of multiple packets, such as a public key packet, a user ID packet, and signature packets. A public key packet alone cannot certify the key itself, so it cannot be used at least in GnuPG. ↩︎

Discussion
とりあえず取れればいい、であれば とすることで取れはしますね
(sshは https://github.com/tsuyoshicho.keys なので、それ的IFがあるのかと、手動でがんばったら見付けたw)
なんと! 気づかなかったです。本文に追記しました。情報ありがとうございます。