This workflow installs, configures and sets up a shell
with GNU Privacy Guard(=gpg=), which is open source and free implementation of the
Open PGP standard-RFC4880, and
some useful utility commands useful.
GNU Privacy Guard(GPG)
Requirements
- Git: distributed version control system
- GNU/GUIX: a functional package management system
- LitDoc: literate programming utility
Introduction
The focus of this workflow is setting up the GNU/Guix gnupg package.
The additional package pinentry implements UI for securely prompting and
reading pass-phrases.
Dependencies
(specifications->manifest '( "gnupg" "pinentry" "rng-tools" ))Usage
To load this workflow run, clone the repository and build it,
git clone https://codeberg.org/distroconfig/gpg guix ld build gpg
To load this workflow into the current shell environment run,
guix ld gpg
Shell Integration
One useful application of gpg is to save sensitive information
that needs to be passed on to applications, as encrypted shell
environment files. And to decrypt and source the files on the fly
at runtime. The following is a shell script for accomplishing that
in Bash,
bin/gpg_decrypt.sh
#! /usr/bin/env bash
#////////////////////////////////////////////////////
# main
#////////////////////////////////////////////////////
[ $# -eq 1 ] || {
echo "ERROR: missing FILE argument"
echo "usage: guix ld gpg -- FILE"
exit 1
}
file="${1}"
[ -r "${file}" ] || {
echo "[ERROR]: unable to read file: ${file}"
exit 1
}
source <$(gpg --decrypt "${file}")The entry point for the script is the main script below,
#! /usr/bin/env bash
source "${LITDOC_DIR}/libs/sh/log.sh"
[ $# -ge 1 ] || {
echo "usage:"
echo "guix ld build gpg"
echo "guix ld decrypt FILE"
}
case ${1} in
configure)
shift
exec "${LITDOC_SITEDIR}/bin/gpg_configure.sh" $@
;;
decrypt)
shift
exec "${LITDOC_SITEDIR}/bin/gpg_decrypt.sh" $@
;;
,*)
log_fail "[gpg]: bad argument: <${@}>"
;;
esacTo run it use,
guix ld gpg -- encrypt FILE # where FILE is file to be encrypted guix ld gpg -- decypt FILE # where FILE is encrypted
Emacs Integration
Configuration for gpg can be found under ~/.gnupg/gpg,
~/.gnupg/gpg.conf ~/.gnupg/gpg-agent.conf
gpg.conf file defaults are often fine, at least for
my personal application. However, the gpg-agent.conf
file contains the pin input prompt UI. In particular
this config, epg-pinentry-mode.
For a smooth Emacs integration, set the option to loopback,
which enables Emacs to prompt for pass-phrase using the mini-buffer
instead of an external program.
# tell pinentry to allow features to divert the passphrase
# entry to a running Emacs instance
#allow-emacs-pinentry
pinentry-program /usr/bin/pinentry-gnome3
# allow clients to use the loopback pinentry features
allow-loopback-pinentryFor the changes to take effect run,
guix ld gpg -- configure
This will execute a shell script shown below,
#!/usr/bin/env bash
source "${LITDOC_DIR}/libs/sh/lit-log.sh"
[ $# -ge 1 ] || {
log_error "bad argument: $@"
echo "usage: guix ld configure"
exit 1
}
gpg --version
gpgconf --reload gpg-agent
gpgconf --kill gpg-agentOnce a key is generated loading the built-in
package epa is sufficient to encrypt and decrypt
files with gpg extension. This also applies to
encrypted elisp files with file extension *.el.gpg or
header info:epa-file-encrypt-to header
# -*- epa-file-encrypt-to: ("user@example.com") -*-
Emacs command for creating and reading encrypted files is available too,
(defun gpg::new-encrypted-file( )
"Opens a new encrypted file"
(interactive)
(let ((buffer (generate-new-buffer "untitled")))
(set-buffer-major-mode buffer)
(with-current-buffer buffer
(goto-char (point-max))
(insert "# -*- epa-file-encrypt-to: (\"aronggile@gmail.com\") -*-"))
(display-buffer buffer '(display-buffer-pop-up-frame . nil))))
When working within Emacs, the EasyPG Assistant(epg) package provides an elisp
interface to gpg. Among other features, the interface implements automatic
encryption and decryption of files with *.gpg extension.
(use-package epg
:config
(setq epa-file-encrypt-to '(user-mail-address))
(setq epg-pinentry-mode 'loopback))Application Notes
Generating GPG Key: run gpg with the full-gen-key option and
select a cryptographic algorithm and curve type. The default is,
elliptic-curve cryptography(option 9) and curve 25519(option 1).
gpg will also prompt for expiration date for the key, where the
default is two years.
gpg --expert --full-gen-key
Backing up GPG Key: once a key is generated it should be backed up prior to use,
gpg --armor --export-secret-keys user@example.com > user.pk.sec
user@example.comis either the user's email address as specified during key generation. Alternatively, it can be the users full name.user.pk.secis file name the private key will be written on.
It is also a good idea to keep key revocation certificate,
gpg --output revoke-cert.asc --gen-revoke user.revoke.sec
Importing GPG Key from a Backup: to import a key that has was
priorly saved, for example to user.pk.sec, run:
gpg --import user.pk.sec gpg --edit-key user@example.com
This will start an interactive session, where gpg asks for
trust, trust-level, and confirmation to have a successful
import.
gpg > trust # invoke trust subcommand > 5 # response to trust level: [ultimate] > y # confirmation: [yes]
View and Edit GPG Key: to edit or change an existing key first list the available public keys using,
# gpg --list-keys
Optionally, use --with-fingerprints option to view the
cryptographically hashed version of the public key, which
is useful when configuring git commit sign-off for example.
gpg-list-keys --with-fingerprints
Enter key editing mode. When prompted for user-id provide the email associated with the key
gpg --edit-key user@email
An interactive session will start. Type in help to list available
commands. To edit expiration date for example, type expires and
then follow the prompt.
Deleting a Key: to delete unused key from a local machine use,
gpg --delete-secret-and-public-keys user@example.com