This workflow installs, configures and sets up shell
commands for working with GNU Privacy Guard(gpg), which
is open source and free implementation of the
Open PGP standard-RFC4880.
GNU Privacy Guard(GPG)
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.
Installation
The Guix manifest for the default packages is listed here. Other dependencies, such as Emacs integration are installed on demand.
(specifications->manifest '( "gnupg" "pinentry" "rng-tools" ))
To load this workflow run,
litdoc 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 a Bash shell,
bin/gpg_decrypt.sh
#! /usr/bin/env bash
#////////////////////////////////////////////////////
# main
#////////////////////////////////////////////////////
[ $# -eq 1 ] || {
echo "ERROR: missing FILE argument"
echo "usage: litdoc 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 "litdoc gpg configure"
echo "litdoc gpg 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: <${@}>"
;;
esac
To run it use,
litdoc gpg encrypt FILE # where FILE is file to be encrypted
litdoc 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-pinentry
For the changes to take effect run,
litdoc site 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: litdoc gpg configure"
exit 1
}
gpg --version
gpgconf --reload gpg-agent
gpgconf --kill gpg-agent
Once 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 '("aronggile@gmail.com"))
(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.com
is either the user's email address as specified during key generation. Alternatively, it can be the users full name.user.pk.sec
is 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