Intro
This post is the first out of two about GnuPG, password management, email, signing and encrypting emails and git commit signing. As always with a helping hand from Emacs. As the posts cover a lot of ground step by step instructions are not desirable. Links to more detailed resources can be found in each section. The main goal is to provide a quick but informative overview and give inspiration for further research.
The big picture is. Use GnuPG to generate asymmetric keys. Generate sub keys for encryption/decryption and signing. Sub keys have a lifetime of 1 year. After 1 year new sub keys for encrypt/decrypt and signing needs to be generated. Use signing sub key to sign git commits. Use encryption/decryption sub key to encrypt/decrypt password files in pass password store. Use Emacs for for gpg pinentry and install a Emacs mode to manage pass passwords.
This posts covers security, but the level of security discussed here can be increased further. Some weaknesses that the post don't cover is. Master key is not generated offline. Master key is not removed from keyring (more info). Public signing sub key is not published to key servers.
The layout of the post:
- Environment; versions of the software.
- GnuGP; how to generate keys and sub key, pinentry, backups.
- Git; how to config git to sign with the gpg sub key.
- Pass; init password store, some basic commands and a quick mention about browserpass.
- Emacs pass mode; quick view of how to config Emacs to use it with
pass
.
If things are unclear, please contact me via twitter!
Environment
Version of the software in use.
Operating system
#+BEGIN_SRC shell :results output code
uname -a
#+END_SRC
#+RESULTS:
#+begin_src shell
Linux arch 5.7.7-arch1-1 #1 SMP PREEMPT Wed, 01 Jul 2020 14:53:16 +0000 x86_64 GNU/Linux
#+end_src
GnuPG
#+BEGIN_SRC shell :results output code
gpg --version
#+END_SRC
#+RESULTS:
#+begin_src shell
gpg (GnuPG) 2.2.20
libgcrypt 1.8.5
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
#+end_src
Pass
#+BEGIN_SRC shell :results output code
pass --version
#+END_SRC
#+RESULTS:
#+begin_src shell
============================================
= pass: the standard unix password manager =
= =
= v1.7.3 =
= =
= Jason A. Donenfeld =
= Jason@zx2c4.com =
= =
= http://www.passwordstore.org/ =
============================================
#+end_src
Emacs
#+BEGIN_SRC shell :results output code
emacs --version
#+END_SRC
#+RESULTS:
#+begin_src shell
GNU Emacs 26.3
Copyright (C) 2019 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
#+end_src
GnuPG
Intro
The first and most important part is GnuPG keys. They are used to encrypt, decrypt and for signing. This post will use one sub key for encryption/decryption and another for signing. The master key will never expire. The sub keys will have a lifetime of 1 year. After that they will be replaced with new sub keys.
This post wont cover the steps of publishing the public signing sub key. But one benefit of publishing new public keys "often" is the acknowledgment of new algorithms. If your published key is very old, it states that you only support old algorithms even if you run the latest GnuPG software. If you wanna know more about publishing keys, more info can be found here and here.
More details about GnuPG keys and sub keys can be found here:
Install
GnuPG on Arch. Together with gpg a collection of pinentry tools is installed.
pacman -S gnupg
Config files
Before start generating keys, make sure that you have this config file in place.
#+BEGIN_SRC shell :results output code
cat ~/.gnupg/gpg.conf
#+END_SRC
#+RESULTS:
#+begin_src shell
personal-digest-preferences SHA256
cert-digest-algo SHA256
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
#+end_src
Create keys
Some of the steps are truncated with ...
and some steps don't show exactly what you
should do. If steps are confusing, turn to the links in the Intro section for guidance.
Start by creating a master key. This key should never expire and it's super important that you keep the master key safe. Bake sure to create a backup and store it offline.
gpg --full-gen-key
Select keys: RSA and RSA
Select keys size: 4096
Valid for: do not expire
Together with the master key, a sub key for encryption is also created. List the keys including sub key fingerprints.
gpg --list-secret-keys --with-subkey-fingerprint
Change the expire time of the encryption sub key to 1 year. This means that you every year need to generate a new encryption subkey from the master key.
gpg --edit-key <MASTER KEY FINGERPRINT>
key <EXISTING ENCRYPT SUB KEY FINGERPRINT>
expire
1y
...
save
Add sub key
This sub key will only be used for signing. After one year it will expire and a new one needs to be created from the master key.
gpg --edit-key <MASTER KEY FINGERPRINT>
addkey
Key: RSA (sign only)
Key size: 4096
Valid for: 1y
...
save
Backup
Create backup and store some place safe!
umask 077; tar -cf $HOME/gnupg-backup.tar -C $HOME .gnupg
Pinentry
pinentry
is the application that is responsible to ask you for the gpg passphrase.
pinentry
have applications for many environments. Such as curses, emacs, gnome, gtk,
qt and tty. I am using pinentry-emacs
. This requires some setup in order for Emacs to
handle pinentry requests.
This is the gpg-agent config that tells it to use Emacs for pinentry:
#+BEGIN_SRC shell :results output code
cat ~/.gnupg/gpg-agent.conf
#+END_SRC
#+RESULTS:
#+begin_src shell
default-cache-ttl 3600
allow-loopback-pinentry
pinentry-program /usr/bin/pinentry-emacs
allow-emacs-pinentry
#+end_src
When gpg need you to provide a passphrase to access gpg resources, it will ask in Emacs minibuffer!
Here is the list of pinentry applications provided by my current Arch GnuPG installation:
#+BEGIN_SRC shell :results output code
pacman -Ql pinentry | awk '{ print $2}' | grep bin/pin
#+END_SRC
#+RESULTS:
#+begin_src shell
/usr/bin/pinentry
/usr/bin/pinentry-curses
/usr/bin/pinentry-emacs
/usr/bin/pinentry-gnome3
/usr/bin/pinentry-gtk-2
/usr/bin/pinentry-qt
/usr/bin/pinentry-tty
#+end_src
Emacs
I run Emacs in server mode and I always have an open Emacs session so when pinentry wants me to provide a passphrase, it does it through Emacs.
Here are the things related to run Emacs as server and to use the pinentry
Emacs
package.
#+BEGIN_SRC shell :results output code
cat ~/.config/systemd/user/emacs.service
#+END_SRC
#+RESULTS:
#+begin_src shell
[Unit]
Description=Emacs text editor
Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/
[Service]
Type=simple
ExecStart=/usr/bin/emacs --fg-daemon --debug-init
ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"
Environment=SSH_AUTH_SOCK=%t/keyring/ssh
Restart=on-failure
[Install]
WantedBy=default.target
#+end_src
#+BEGIN_SRC shell :results output code
cat ~/.bin/start-emacs
#+END_SRC
#+RESULTS:
#+begin_src shell
#!/bin/bash
emacsclient -nc
#+end_src
#+BEGIN_SRC shell :results output code
systemctl --user status emacs.service # Service status
systemctl --user enable emacs.service # Start service on boot
systemctl --user start emacs.service # Start service
systemctl --user stop emacs.service # Stop service
journalctl --user -u emacs.service # Service stdout
#+END_SRC
#+BEGIN_SRC shell :results output code
cat ~/.emacs.d/packages.el | awk 'NR==7,NR==11'
#+END_SRC
#+RESULTS:
#+begin_src shell
(use-package pinentry
:pin melpa
:config
(setf epa-pinentry-mode 'loopback)
(pinentry-start))
#+end_src
keys -> qr code
To get the keys to my phone I exported them from the keychain and into qr codes. Then used imagemagick to show each of them for some seconds before showing the next one. When key size is 4096 they don't fit into one qr image.
The qr codes can also be printed and kept in a safe as a secure backup.
mkdir -p /tmp/keys-export && cd $_
gpg --export-secret-keys --armor <SUB KEY FINGERPRINT> > sub.key
split -C 2500 sub.key splitkey-
for file in splitkey-??; do <"$file" qrencode -s 3 -d 150 -o "$file".qr; done
display -delay 50 *.qr
cd /tmp && rm -rf keys-export
Git
Now when there is a key to sign with it's time to configure git to use it.
First, get the fingerprint of your signing key.
gpg --list-secret-keys --with-subkey-fingerprint
Then tell git to gpg sign commits and what sub key fingerprint to use when doing so. It should be a '!' in the end of the fingerprint. It tells gpg that it's a sub key.
git config --global commit.gpgSign true
git config --global user.signingKey <SIGN SUBKEY FINGERPRINT>\!
Lets see how the git config looks like.
#+BEGIN_SRC shell :results output code
cat ~/.gitconfig
#+END_SRC
#+RESULTS:
#+begin_src shell
[user]
email = jherrlin@gmail.com
name = John Herrlin
signingKey = 6699DFA319365AAD1CE757040EE8540AE7F042B2!
[commit]
gpgSign = true
#+end_src
Export your public sign sub key to provide it to a git hosting platform like GitHub or Bitbucket. Or to your colleagues.
gpg --export --armor 6699DFA319365AAD1CE757040EE8540AE7F042B2 > /tmp/public-sign.key
From now on all of your git commits are signed with your private sign sub key. Now people can be more ensured that it's you that made the change.
Pass
pass
, "the standard unix password manager" is a nice way of managing passwords. It
uses gpg encrypted files that are stored locally on your computer. As they are just
files they can be version controlled and used in ways you are used to handle files.
There are a couple of extensions to pass
to make it interact with a web browser and
for usage of your passwords on your mobile device. And of course there is a Emacs mode!
Here are a couple of resources for pass
.
- https://www.passwordstore.org/
- https://github.com/browserpass/browserpass-native
- https://github.com/browserpass/browserpass-extension
- https://lists.zx2c4.com/pipermail/password-store/2018-January/003178.html
Install pass and browser extensions
On Arch, all of the packages are in the repo.
pacman -S pass browserpass browserpass-chromium
Init pass
Create a new store and provide your gpg id. Pass also have built in support for git.
pass init <ENCRYPT SUB KEY FINGERPRINT>!
pass git init
Insert new pass
Add a password to the password store.
pass insert fsf.org
Retrieve password
Get the password to stdout.
pass show fsf.org
More
pass
have many more options, check them out.
pass --help
Browserpass
Install browser pass extension using the installation steps here.
Emacs pass mode
There is a good Emacs package calls pass
. I use use-package
to install it. To enter
pass
within Emacs use M-x pass
.
#+BEGIN_SRC shell :results output code
cat ~/.emacs.d/packages.el | awk 'NR==13,NR==16'
#+END_SRC
#+RESULTS:
#+begin_src shell
(use-package pass
:pin melpa
:config
(setf epa-pinentry-mode 'loopback))
#+end_src