I've set up mu4e, and have my Gmail credentials stored in two files:
.offlineimaprc
- this file is used by Offlineimap to connect to my Gmail and sync my inbox with mu4e..authinfo
- that file stores my Gmail credential, and used by Emacs to send emails.
Unfortunately, both of those files are plain text, and though I’m not a security freak, I’m uncomfortable storing my passwords out in the open. So, I went ahead to find out how to encrypt them. Most of the tutorials I read were too technical, and covered much more than my simple usecase. It’s not that I couldn’t follow theme, but I know I wouldn’t have retained the information, and able to retract my steps if I needed to in the future.
My goal with this post was to create a simple guide on how to install
gpg, generate a key, and use it in mu4e. I failed... I thought I will be
able to it non-technical for the most part, but once getting to
configure Emacs and mu4e to work with gpg, I had to delve into some
heavy configuration, which included the creation of a python script to
work along Offlineimap... The good thing is that this guide will help
you get Emacs and mu4e work with an encrypted version of a .authinfo
file, and your credentials will remain secret.
Now that our expectations are set, and assuming you're up for the ride, lets start this journey.
Installing GPG
~ $ brew install gpg
Let's make sure gpg was installed:
~ $ gpg --version
Figure 1: gpg version information along with the list of supported algorithms
Now really, the most informative source of information is gpg's help. Go ahead and skim it:
~ $ gpg -h
Create a key
~ $ gpg --gen-key
There’s a simple wizard that lets you set the encryption type, and asks for your name, email address and other comments. Those details will be associated with your key.
Next, you’ll be asked to create a passphrase. This is like the password to your secret key. If you lose it, you’ll have no access to any of the information encrypted with this key. So don’t ever lose it…
Here’s how this flow looks like:
~ $ gpg --gen-key
gpg (GnuPG) 1.4.19; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"
Real name: Jane Roe
Email address: jane@example.com
Comment: lorem ipsum
You selected this USER-ID:
"Jane Roe (lorem ipsum) <jane@example.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
..........+++++
.+++++
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
..........+++++
...+++++
gpg: key 86B62C98 marked as ultimately trusted
public and secret key created and signed.
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u
pub 2048R/86B62C98 2016-02-17
Key fingerprint = 42FD C031 BD51 4CC8 7C02 EA14 35D4 80A2 86B6 2C98
uid Jane Roe (lorem ipsum) <jane@example.com>
sub 2048R/8C0D5E5D 2016-02-17
~ $
Now that you've created a key, you can go ahead and sign the .authinfo
file.
Sign and encrypt the .authinfo
file1
~ $ gpg -se .authinfo
You'll be asked for your passphrase. Enter it, and the .authinfo
will
be signed, and renamed to .authinfo.gpg
EmacsWiki suggests to limit permission to this file. I find it important:
~ $ chmod 600 .authinfo.gpg
Back in Emacs, there are couple of changes we need to make in order for
mu4e to start working with the ,authinfo.gpg
file. I wish I read this
gist before, because it covers
those changes succinctly, but here is a summary of those modifications:
Changes to .offlineimaprc
Two additions:
- A reference to a python file where you'll store a function to fetch
your credentials from the
.authinfo.gpg
file - Under the
[Repository Remote]
section add the call to theget_password_emac
function
Here's how your .offlineimaprc
file will look like afterwards:
[general]
accounts = Gmail
maxsyncaccounts = 3
pythonfile = ~/.offlineimap.py
[Account Gmail]
localrepository = Local
remoterepository = Remote
[Repository Local]
type = Maildir
localfolders = ~/Maildir
[Repository Remote]
type = IMAP
remoteuser = yanivdll@gmail.com
remotehost = imap.gmail.com
remotepasseval = get_password_emacs("imap.gmail.com", "yanivdll@gmail.com", "993")
ssl = yes
sslcacertfile = /usr/local/etc/openssl/certs/ca-bundle.crt
maxconnections = 1
realdelete = no
Add a .offlineimap.py
file
This file will define the get_password_emac
function:
#!/usr/bin/python
import re, os
def get_password_emacs(machine, login, port):
s = "machine %s login %s port %s password ([^ ]*)\n" % (machine, login, port)
p = re.compile(s)
authinfo = os.popen("gpg -q --no-tty -d ~/.authinfo.gpg").read()
return p.search(authinfo).group(1)
Changes to mu4e config
Lastly, in your Emacs config, under the mu4e smtp settings, add a reference to the encrypted auth file:
...
(setq message-send-mail-function 'smtpmail-send-it
starttls-use-gnutls t
smtpmail-starttls-credentials
'(("smtp.gmail.com" 465 nil nil))
smtpmail-auth-credentials
(expand-file-name "~/.authinfo.gpg")
smtpmail-default-smtp-server "smtp.gmail.com"
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 465
smtpmail-debug-info t)
...
Now, you're emails should be sent using the .authinfo.gpg
file. Go on
and try it2. Note that before actually sending the email, Emacs will ask for your pass-phrase3
Extras
Backup private key
I stored all the information related to my gpg key, as well as a backup file in my 1password. Here's how I created the key backup:
~ $ gpg --export-secret-keys --armor jane@example.com > jroe-privkey.asc
Important: Make sure to store the output file in a secure place; it contains your private key in plain text.
Encrypt text in Emacs
- Mark the text you would like to encrypt
- Run
M-x epa-encrypt-region
- Mark the key you would like to use for encryption
Now the encrypted text will replace the original, plain, text:
Figure 2: M-x epa-encrypt-region
will encrypt a region of text in Emacs
Decrypt text
To decrypt a message, or a file you've encrypted:
- Mark the text you would like to decrypt (you'll have to mark also the header and footer of the message)
-
Run
M-x epa-decrypt-region
Figure 3:
M-x epa-decrypt-region
will decrypt a region of text in Emacs -
Enter your pass-phrase
- Emacs will ask if you want the decrypted text to replace the original text. If you choose "No", it will open the text in a second window.
Figure 4: The decrypted text in a second window
That's it. If you're interested in more than the basics that I went through above, try the links bellow.
Reference
- Gnupg - documentation
- Using gpg in emacs - EasyPG Assistant user’s manual
- Fedora Wiki pages - GPG essentials
- EmacsWiki - GnusAuthinfo
- Tricotism - EasyPG for Emacs on OS X, or sometimes Emacs doesn’t load the env paths you might expect
- ubuntu forums Encrypting and decrypting a message
-
Made an edit here (initially, I only signed the file, without encrypting it). Thanks /u/aminab for the correction. ↩
-
If you still have the
.authinfo
file, rename it. Once we see that mu4e sends emails using the encrypted version of the auth file, we can dispose this, decrypted, version of it. ↩ -
If Emacs asks for your passphrase too often, you might find this comment in Reddit, by /u/aminb, helpful. ↩