feature: add gpg-pubkey

This commit is contained in:
AJ ONeal
2021-11-14 08:18:32 +00:00
parent 5394796d1a
commit 5b97c474ab
7 changed files with 505 additions and 0 deletions
+239
View File
@@ -0,0 +1,239 @@
---
title: GnuPG Pub Key
homepage: https://webinstall.dev/gpg-pubkey
tagline: |
Get your GnuPG Public Key.
---
## Cheat Sheet
> Your GnuPG Public Key can be used for signing git commits and email, among
> other things. The file public key ends in `.asc`.
This installs two commands.
- `gpg-pubkey` will:
1. Create a new gpg keypair if you dont already have one \
(uses `~/.gitconfig` for name and email)
2. Copy your new or existing GnuPG Public Key to your `Downloads` folder
3. Print the location of the copied key, and its contents, to the screen
- `gpg-pubkey-id` will output the id of your public key.
The easiest way to get your GnuPG Public Key:
```bash
curl https://webinstall.dev/gpg-pubkey | bash
```
This is what the output of `gpg-pubkey` looks like (except much longer):
```txt
GnuPG Public Key ID: CA025BC42F00BBBE
~/Downloads/john@example.com.gpg.asc:
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGGLrUIBEAC+k1rHvi4xbCiN/cnh3Zi4rbKeJdPIWDP0wDhZcYzIN4/ZWVAm
... (several lines omitted for brevity)
nZH7UhxDx6Gu4w1+uef0E/cjz2BuEn/LN9UBGWwI5dLp5p03FeXYzzAwt6sh
=rRiF
-----END PGP PUBLIC KEY BLOCK-----
```
Note: Your public key is the _entire_ section starting with and including
`-----BEGIN` all the way to and including `BLOCK-----`
### Files
These are the files / directories that are created and/or modified with this
install:
```txt
~/.config/envman/PATH.env
~/.local/bin/gpg-pubkey
~/.local/bin/gpg-pubkey-id
~/.gnupg/
~/Downloads/YOU.KEY_ID.gpg.asc
```
## How to add your GPG Public Key to GitHub
1. Go to your GitHub Profile (<https://github.com/settings/profile>)
2. Go to the SSH and GPG Keys (<https://github.com/settings/keys>)
3. Add GPG Key (<https://github.com/settings/gpg/new>)
4. Paste the output of `gpg-pubkey` into the form
## How to automatically sign your git commits
Run `gpg-pubkey-id` to get your GnuPG Public Key ID and then update your
`~/.gitconfig` to sign with it by default:
```bash
#!/bin/bash
MY_KEY_ID="$(
gpg-pubkey-id
)"
git config --global user.signingkey "${MY_KEY_ID}"
git config --global commit.gpgsign true
git config --global log.showSignature true
```
Or, for Windows users:
```bash
#!/usr/bin/env pwsh
$my_key_id = gpg-pubkey-id
git config --global user.signingkey "$my_key_id"
git config --global commit.gpgsign true
git config --global log.showSignature true
```
## How to use `gpg` manually
- How to get your Public Key ID
- How to export your Public Key
- How to create a Private Key
### How to get your GnuPG Public Key ID
All _Secret Keys_ have _Public IDs_ (and corresponding _Public Keys_).
Here's a command to list your secret key(s) and get the Public ID (of the first
one, if you have many):
```bash
#!/bin/bash
MY_KEY_ID="$(
gpg --list-secret-keys --keyid-format LONG |
grep sec |
cut -d'/' -f2 |
cut -d' ' -f1
)"
echo "$MY_KEY_ID"
```
Or, for Windows users:
```pwsh
#!/usr/bin/env pwsh
$my_key_id = (
gpg --list-secret-keys --keyid-format LONG |
Select-String -Pattern '\.*sec.*\/' |
Select-Object Line |
ForEach-Object {
$_.Line.split('/')[1].split(' ')[0]
}
)
echo "$my_key_id"
```
Let's break that down, for good measure:
All secret keys have a Public Key and a Public ID, which can be viewed in _LONG_
format:
```bash
gpg --list-secret-keys --keyid-format LONG
```
```txt
/Users/me/.gnupg/pubring.kbx
----------------------------
sec rsa3072/CA025BC42F00BBBE 2021-11-10 [SCEA]
6F848282295B19123748D36BCA025BC42F00BBBE
uid [ultimate] John Doe (mac.local) <john@example.com>
ssb rsa3072/674124162BF19A32 2021-11-10 [SEA]
```
The line with the Public Key ID is the one that starts with `sec`:
```txt
sec rsa3072/CA025BC42F00BBBE 2021-11-10 [SCEA]
```
Specifically, it's the part just after the `/` - **CA025BC42F00BBBE**, in this
case.
Note: It's important that you list the Secret Keys, because listing Public Keys
will show all keys that you trust in your gpg keychain (co-workers, for
example), not just keys that you own.
### How to export your GnuPG Public Key:
Here's how to copy your Public Key into your Downloads folder:
```bash
gpg --armor --export "${MY_KEY_ID}" > ~/Downloads/"${MY_EMAIL}".gpg.asc
```
Or, if you just want to print it to your console, run this:
```bash
gpg --armor --export "${MY_KEY_ID}"
```
### How to create an GnuPG Private Key:
Generally speaking you'll want to use the same name and email for `git` and
`gpg`.
Here's how you can automate creating a key using the same info as what's in your
`~/.gitconfig`:
```bash
#!/bin/bash
MY_NAME="$( git config --global user.name )"
MY_HOST="$( hostname )"
MY_EMAIL="$( git config --global user.email )"
gpg --batch --generate-key << EOF
%echo Generating RSA 3072 key
Key-Type: RSA
Key-Length: 3072
Subkey-Type: RSA
Subkey-Length: 3072
Name-Real: ${MY_NAME}
Name-Comment: ${MY_HOST}
Name-Email: ${MY_EMAIL}
Expire-Date: 0
%commit
EOF
```
Or, for the Windows folk...
```bash
#!/usr/bin/env pwsh
$my_name = git config --global user.name
$my_host = hostname
$my_email = git config --global user.email
echo "
%echo Generating RSA 3072 key
Key-Type: RSA
Key-Length: 3072
Subkey-Type: RSA
Subkey-Length: 3072
Name-Real: $my_name
Name-Comment: $my_host
Name-Email: $my_email
Expire-Date: 0
%commit
" | gpg --batch --generate-key
```
Note: if you want to create a key without a passphrase, add
`--pinentry=loopback --passphrase=''` to the arguments.
(though typically it's better to create a random passphrase and just let macOS
store it in your user Keychain and forget it - just so it doesn't get backed up
unencrypted, etc)
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env pwsh
gpg --list-secret-keys --keyid-format LONG |
Select-String -Pattern '\.*sec.*\/' |
Select-Object Line |
ForEach-Object {
$_.Line.split('/')[1].split(' ')[0]
}
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
set -e
set -u
gpg --list-secret-keys --keyid-format LONG |
grep sec |
cut -d'/' -f2 |
cut -d' ' -f1
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env pwsh
$my_key_id = gpg --list-secret-keys --keyid-format LONG |
Select-String -Pattern '\.*sec.*\/' |
Select-Object Line |
ForEach-Object {
$_.Line.split('/')[1].split(' ')[0]
}
if (!$my_key_id)
{
$my_name = git config --global user.name
$my_email = git config --global user.email
$my_host = hostname
echo "
%echo Generating RSA 3072 key
Key-Type: RSA
Key-Length: 3072
Subkey-Type: RSA
Subkey-Length: 3072
Name-Real: $my_name
Name-Comment: $my_host
Name-Email: $my_email
Expire-Date: 0
%commit
" | gpg --batch --generate-key
}
$my_asc_relpath = "Downloads/$my_email.$my_key_id.gpg.asc"
& gpg --armor --export $my_key_id > "$Env:USERPROFILE/$my_asc_relpath"
# TODO use the comment (if any) for the name of the file
$my_email = git config --global user.email
echo ""
echo "GnuPG Public Key ID: $MY_KEY_ID"
echo ""
echo "~/$my_asc_relpath":
echo ""
& type "$Env:USERPROFILE/$my_asc_relpath"
echo ""
+131
View File
@@ -0,0 +1,131 @@
#!/bin/bash
set -e
set -u
function __get_git_email() {
grep 'email\s*=.*@' ~/.gitconfig |
tr -d '\t ' | head -n 1 |
cut -d'=' -f2
}
function __get_pubkey_id() {
gpg --list-secret-keys --keyid-format LONG |
grep sec |
cut -d'/' -f2 |
cut -d' ' -f1
}
function _create_gpg_key() {
if [[ ! -e ~/.gitconfig ]]; then
return 1
fi
MY_NAME="$(
grep 'name\s*=' ~/.gitconfig |
head -n 1 |
cut -d'=' -f2 |
sed -e 's/^[\t ]*//'
)"
if [[ -z ${MY_NAME} ]]; then
return 1
fi
MY_EMAIL="$(
__get_git_email
)"
if [[ -z ${MY_EMAIL} ]]; then
return 1
fi
MY_HOST="$(hostname)"
# Without passphrase:
#gpg --batch --generate-key --pinentry=loopback --passphrase=''
# With passphrase via macOS Keychain
gpg_opts="
%echo Generating RSA 3072 key...
%echo Warning: It may take several minutes to gather enough entropy,
%echo especially on a linux VPS if haveged isn't installed.
%echo (try moving the mouse, downloading large files, etc)
Key-Type: RSA
Key-Length: 3072
Subkey-Type: RSA
Subkey-Length: 3072
Name-Real: ${MY_NAME}
Name-Comment: ${MY_HOST}
Name-Email: ${MY_EMAIL}
Expire-Date: 0
%commit
"
if ! echo "$gpg_opts" | gpg --batch --generate-key 2> /dev/null; then
echo >&2 ""
echo >&2 ""
echo >&2 ""
echo >&2 "== STOP! CHOOSE A PASSPHRASE =="
echo >&2 ""
echo >&2 "Choose a passphrase for this GPG Key."
echo >&2 "(the passphrase will not be shown as you type)"
echo >&2 ""
echo >&2 -n "Passphrase: "
read -r -s
echo >&2 ""
echo "
%echo Generating RSA 3072 key...
%echo Warning: It may take several minutes to gather enough entropy,
%echo especially on a linux VPS if haveged isn't installed.
%echo (try moving the mouse, downloading large files, etc)
Key-Type: RSA
Key-Length: 3072
Subkey-Type: RSA
Subkey-Length: 3072
Name-Real: ${MY_NAME}
Name-Comment: ${MY_HOST}
Name-Email: ${MY_EMAIL}
Passphrase: ${REPLY}
Expire-Date: 0
%commit
" --batch --generate-key > gpg
fi
echo >&2 "Done"
}
# (maybe) Create first key
if ! gpg --list-secret-keys | grep -q sec; then
if ! _create_gpg_key; then
echo >&2 ""
echo >&2 "Please set your name and email, and then try again:"
echo >&2 ""
echo >&2 " git config --global user.name 'John Doe'"
echo >&2 " git config --global user.email johndoe@example.com"
echo >&2 " gpg-pubkey"
echo >&2 ""
echo >&2 "(or manually create a private key first)"
echo >&2 ""
exit 1
fi
fi
MY_KEY_ID="$(
__get_pubkey_id
)"
MY_EMAIL="$(
__get_git_email
)"
#gpg --send-keys "${MY_KEY_ID}"
MY_ASC_RELPATH="Downloads/${MY_EMAIL}.${MY_KEY_ID}.gpg.asc"
mkdir -p ~/Downloads/
rm -f ~/"${MY_ASC_RELPATH}"
gpg --armor --export "${MY_KEY_ID}" > ~/"${MY_ASC_RELPATH}"
echo >&2 ""
echo >&2 "GnuPG Public Key ID: ${MY_KEY_ID}"
echo >&2 ""
#shellcheck disable=SC2088
echo >&2 "~/${MY_ASC_RELPATH}":
echo >&2 ""
cat ~/"${MY_ASC_RELPATH}"
echo >&2 ""
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env pwsh
#
# gpg-pubkey-id
#
$MY_CMD = "gpg-pubkey"
$MY_SUBCMD = "gpg-pubkey-id"
& curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_HOST/packages/$MY_CMD/$MY_SUBCMD.ps1" -o "$Env:USERPROFILE\.local\bin\$MY_SUBCMD.ps1.part"
Remove-Item -Path "$Env:USERPROFILE\.local\bin\$MY_SUBCMD.ps1" -Recurse -ErrorAction Ignore
& move "$Env:USERPROFILE\.local\bin\$MY_SUBCMD.ps1.part" "$Env:USERPROFILE\.local\bin\$MY_SUBCMD.ps1"
Set-Content -Path "$Env:USERPROFILE\.local\bin\$MY_SUBCMD.bat" -Value "@echo off`r`npushd %USERPROFILE%`r`npowershell -ExecutionPolicy Bypass .local\bin\$MY_SUBCMD.ps1 %1`r`npopd"
#
# gpg-pubkey
#
$MY_CMD = "gpg-pubkey"
& curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_HOST/packages/$MY_CMD/$MY_CMD.ps1" -o "$Env:USERPROFILE\.local\bin\$MY_CMD.ps1.part"
Remove-Item -Path "$Env:USERPROFILE\.local\bin\$MY_CMD.ps1" -Recurse -ErrorAction Ignore
& move "$Env:USERPROFILE\.local\bin\$MY_CMD.ps1.part" "$Env:USERPROFILE\.local\bin\$MY_CMD.ps1"
Set-Content -Path "$Env:USERPROFILE\.local\bin\$MY_CMD.bat" -Value "@echo off`r`npushd %USERPROFILE%`r`npowershell -ExecutionPolicy Bypass .local\bin\$MY_CMD.ps1 %1`r`npopd"
#
# Check the gpg exists
#
$gpg_exists = Get-Command gpg 2> $null
if (!$gpg_exists) {
curl.exe "$Env:WEBI_HOST/gpg" | powershell
$gpg_exists = Get-Command gpg 2> $null
if (!$gpg_exists) {
echo ""
echo "(exited because gpg is not existalled)"
echo ""
Exit 1
}
}
#
# run gpg-pubkey
#
& "$Env:USERPROFILE\.local\bin\$MY_CMD.bat"
+35
View File
@@ -0,0 +1,35 @@
#!/bin/bash
set -e
set -u
function __install_gpg_pubkey() {
MY_CMD="gpg-pubkey"
rm -f "$HOME/.local/bin/$MY_CMD"
webi_download "$WEBI_HOST/packages/$MY_CMD/$MY_CMD.sh" "$HOME/.local/bin/$MY_CMD"
chmod a+x "$HOME/.local/bin/$MY_CMD"
}
function __install_gpg_pubkey_id() {
MY_CMD="gpg-pubkey"
MY_SUBCMD="gpg-pubkey-id"
rm -f "$HOME/.local/bin/$MY_SUBCMD"
webi_download "$WEBI_HOST/packages/$MY_CMD/$MY_SUBCMD.sh" "$HOME/.local/bin/$MY_SUBCMD"
chmod a+x "$HOME/.local/bin/$MY_SUBCMD"
}
function __check_gpg_exists() {
if ! command -v gpg; then
webi gpg
export PATH="$HOME/.local/opt/gnupg/bin:$PATH"
export PATH="$HOME/.local/opt/gnupg/bin/pinentry-mac.app/Contents/MacOS:$PATH"
fi
}
__install_gpg_pubkey_id
__install_gpg_pubkey
__check_gpg_exists
# run the command
"$HOME/.local/bin/$MY_CMD"