Skip to content

Instantly share code, notes, and snippets.

@justenwalker
Last active October 21, 2021 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justenwalker/f78df68687eb8ad4132d0222936f50e0 to your computer and use it in GitHub Desktop.
Save justenwalker/f78df68687eb8ad4132d0222936f50e0 to your computer and use it in GitHub Desktop.
Generate ECC GPG Key
#!/bin/bash
# Usage: gpg-gen.sh
#
# Generates a new ECC GPG Key with a random passphrase
# It will output the resulting keys to ~/gpg-keys/
# You should save these somewhere safe like 1Password
set -euo pipefail
PRIMARY_KEY_EXPIRATION=3y
SUB_KEY_EXPIRATION=1y
export TEMP="$(mktemp -d)"
cleanup() {
if [ -n "$TEMP" ] && [ -d "$TEMP" ]; then
rm -rf $TEMP
else
echo "$TEMP untouched" >&2
fi
}
trap cleanup EXIT
OLD_GNUPGHOME=${GNUPGHOME:-""}
export GNUPGHOME="${TEMP}/.gnupg"
mkdir -p $GNUPGHOME
chmod 700 $GNUPGHOME
promptName() {
echo -n "Full Name: "
read FULLNAME
echo -n "E-Mail Address: "
read EMAIL
cat <<EOF
Full-Name : ${FULLNAME}
E-mail : ${EMAIL}
EOF
echo -n "Is this correct? [Y/n]: "
read YN
case $YN in
Y|y|yes)
return 0
;;
N|n|no)
return 1
;;
*)
echo "Unexpected response: ${YN}" >&2
exit 1
;;
esac
}
while ! promptName; do
true
done
PASSPHRASE=$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | sha256sum -b | sed 's/ .*//')
gpg -q --batch \
--passphrase "${PASSPHRASE}" \
--quick-generate-key "${FULLNAME} <${EMAIL}>" \
ed25519 cert ${PRIMARY_KEY_EXPIRATION} 2>&1 > /dev/null
FPR=$(gpg --list-options show-only-fpr-mbox --list-secret-keys 2>/dev/null | awk '{print $1}')
echo $PASSPHRASE | gpg -q --batch --yes --passphrase-fd 0 --pinentry-mode loopback \
--quick-add-key $FPR ed25519 sign ${SUB_KEY_EXPIRATION} 2>/dev/null
echo $PASSPHRASE | gpg -q --batch --yes --passphrase-fd 0 --pinentry-mode loopback \
--quick-add-key $FPR cv25519 encrypt ${SUB_KEY_EXPIRATION} 2>/dev/null
echo $PASSPHRASE | gpg -q --batch --yes --passphrase-fd 0 --pinentry-mode loopback \
--quick-add-key $FPR ed25519 auth ${SUB_KEY_EXPIRATION} 2>/dev/null
mkdir -p "${TEMP}/export"
chmod 700 "${TEMP}/export"
pubkey=${FPR}.pub.asc
seckey=${FPR}.sec.asc
revkey=${FPR}.rev.txt
gpg --batch \
--armor --output "${TEMP}/export/${pubkey}" \
--export $FPR
echo $PASSPHRASE | gpg --batch --yes --passphrase-fd 0 --pinentry-mode loopback \
--armor --output "${TEMP}/export/${seckey}" \
--export-secret-key $FPR
if [ -f ${GNUPGHOME}/openpgp-revocs.d/${FPR}.rev ]; then
cp ${GNUPGHOME}/openpgp-revocs.d/${FPR}.rev "${TEMP}/export/${revkey}"
fi
mkdir -p "${HOME}/gpg-keys"
chmod 700 "${HOME}/gpg-keys"
OUT_DIR="${HOME}/gpg-keys"
cp ${TEMP}/export/* "${OUT_DIR}"
echo "=== Generated GPG Key: ${FPR} ==="
gpg --list-keys ${FPR}
cat <<EOF >&2
Public Key: ${HOME}/gpg-keys/${pubkey}
This is the public key and should distributed somewhere publicly accessible
Such as a shared drive, website, keyserver.
Secret Key: ${OUT_DIR}/${seckey}
This is the SECRET key. Keep this safe!
Import this key into your keychain with:
$ gpg --import ${OUT_DIR}/${seckey}
gpg: key ${FPR: -16}: public key "${FULLNAME} <${EMAIL}>" imported
gpg: key ${FPR: -16}: secret key imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
You'll also need to trust this key with:
$ echo "${FPR}:6:" | gpg --import-ownertrust
gpg: inserting ownertrust of 6
The passphrase is currently '${PASSPHRASE}'
You can change it after you've imported it with:
$ gpg --edit-key ${FPR}
gpg> passwd
gpg> save
Revocation Key: ${OUT_DIR}/${revkey}
This is a pre-generated Revocation key. Keep this safe!
It is only used for revoking a key you lost access to.
You can always generate revocations yourself if you still have access to your key with:
$ gpg --gen-revoke ${FPR}
EOF
echo -n "Do you want to import this key right now? [Y/n]: "
read YN
case $YN in
Y|y|yes)
export GNUPGHOME=${OLD_GNUPGHOME}
echo "The passphrase is currently '${PASSPHRASE}'."
echo "Copy this because you'll need it to import into your keychain."
echo "Press ENTER when you are ready..."
read ENTER
gpg --import ${OUT_DIR}/${seckey}
echo "Trusting the key"
echo "${FPR}:6:" | gpg --import-ownertrust
exit 0
;;
N|n|no)
exit 0
;;
*)
echo "Unexpected response: ${YN}" >&2
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment