Last active
October 21, 2021 19:22
-
-
Save justenwalker/f78df68687eb8ad4132d0222936f50e0 to your computer and use it in GitHub Desktop.
Generate ECC GPG Key
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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