Version 15 (modified by MichaelRay, 4 years ago) (diff)

more style fixes

The purpose of this guide is to show the configuration and usage of mutt with GnuPG.

A working knowledge of both mutt, gnupg and a general understanding of the mail encryption/security is assumed throughout this document. In order to become familiar with these issues, please read one or both of these documents:

I'm using mutt version 1.5.13 and gnupg 1.4.5. You can check both programs versions using the command line option --version.


  • Understanding of mail encryption and the web of trust
  • Have both mutt and gnupg installed and working properly.
  • A keyring with both public and private keys.

You can list all the keys in your gnupg keyring with:

gpg --list-keys

Typically the output consists of lines of the type:

pub   2048R/DEADBEEF 2010-05-01 [expired: 2012-04-30]
uid                  Alice Glass <>

pub   2048R/1234ABCD 2012-12-18 [expires: 2014-12-18]
uid                  Alice Glass <>

The key ID (identifier) is the sequence of hexadecimal digits which comes after the "/", for example in these cases they are DEADBEEF and 1234ABCD. You should verify that your key is not expired.

Mutt setup and explanation

These are the settings from the mutt-gnupg-howto. You can put these in some file, for example in ~/.mutt/crypto file, and source it in your main muttrc file with:

source ~/.mutt/crypto

or you can directly copy and paste it in your muttrc.

NOTE: The pgp_encrypt_only_command and pgp_encrypt_sign_command contain an instruction to also encrypt the message using the author's public key. That is the option, "--encrypt-to 0xC9C40C31". If you want to automatically encrypt messages to yourself (for the Sent folder, for example), replace 0xC9C40C31 with your public key's id. Otherwise, remove the entire --encrypt-to 0xC9C40C31. You will get an error message about not finding the public key if you leave it as-is.

set pgp_decode_command="gpg %?p?--passphrase-fd 0? --no-verbose --batch --output - %f"
set pgp_verify_command="gpg --no-verbose --batch --output - --verify %s %f"
set pgp_decrypt_command="gpg --passphrase-fd 0 --no-verbose --batch --output - %f"
set pgp_sign_command="gpg --no-verbose --batch --output - --passphrase-fd 0 --armor --detach-sign --textmode %?a?-u %a? %f"
set pgp_clearsign_command="gpg --no-verbose --batch --output - --passphrase-fd 0 --armor --textmode --clearsign %?a?-u %a? %f"
set pgp_encrypt_only_command="pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust --encrypt-to 0xC9C40C31 -- -r %r -- %f"
set pgp_encrypt_sign_command="pgpewrap gpg --passphrase-fd 0 --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust --encrypt-to 0xC9C40C31 -- -r %r -- %f"
set pgp_import_command="gpg --no-verbose --import -v %f"
set pgp_export_command="gpg --no-verbose --export --armor %r"
set pgp_verify_key_command="gpg --no-verbose --batch --fingerprint --check-sigs %r"
set pgp_list_pubring_command="gpg --no-verbose --batch --with-colons --list-keys %r" 
set pgp_list_secring_command="gpg --no-verbose --batch --with-colons --list-secret-keys %r" 

# specify the uid to use when encrypting/signing
set pgp_sign_as=0x12345678

# this set the number of seconds to keep in memory the passphrase used to encrypt/sign
# the more the less secure it will be
set pgp_timeout=60

# it's a regexp used against the GPG output: if it matches some line of the output
# then mutt considers the message a good signed one (ignoring the GPG exit code)
set pgp_good_sign="^gpg: Good signature from"

# mutt uses by default PGP/GPG to sign/encrypt messages
# if you want to use S-mime instead set the smime_is_default variable to yes

# automatically sign all outgoing messages
set crypt_autosign
# sign only replies to signed messages
set crypt_replysign

# automatically encrypt outgoing messages
set crypt_autoencrypt=yes
# encrypt only replies to signed messages
set crypt_replyencrypt=yes
# encrypt and sign replies to encrypted messages
set crypt_replysignencrypted=yes

# automatically verify the sign of a message when opened
set crypt_verify_sig=yes

The mutt UI idea while dealing with encrypted mails is to automatically decrypt an encrypted message when it is opened. In a similar way it will optionally verify the authenticity of a signed message (depending on the crypt_verify_sig variable) when it is opened.

The status flag defined in the $index_format variable for the index, will show a relevant flag for each signed/encrypted message. They are:

  • s if the message is signed and not yet verified
  • S if the message is signed and the signature is successfully verified
  • P if the message is PGP encrypted

In order to be considered completely sure, all the parts of the message have to be signed. If this is not the case mutt won't consider the message completely sure, and the flag will stay "s": this happens for example when a signed message is processed by a mailing-list software and a trailing mailing-list signature is applied to it.

Publication of your public key

There are different public keyservers, each one implementing one or more different access methods: HKP, WWW, FTP, mail, LDAP. An important thing to understand about keyservers is that they're synchronized, i.e. they tend to share the same public keys.

So in order to get published your public key in just one of these you only need to public it in just one keyserver, then wait for the change to be propagated through all the keyservers.

Here it is a list of public keyservers (from the default gpg.conf file):


To public your public key do this:

gpg --send-key <key id>

and the corresponding key will be published in the specified keyserver (and in all others). Now your public key is public, congratulations!

The publication on a public keyserver is not definitively the only method possible: there is the possibility to use a web page, to send it through ordinary mail or email, or via web. Note that all of these methods are subject to a man in the middle attack: the more the number of methods you'll use, the less are the chances that some very determined malicious individual will stole your identity. Note also that the shared publication of your public key highly decreases the possibility of your public key be compromised, since the attacker should compromise <b>at the same time</b> all the keyservers.

In case of web publication you can attach an header to your outgoing mail as this:


in order to inform your recipient of the web address of your public key. The content of the page can be generated with:

gpg --export --armor

In mutt you can set this with the command:


Or if you don't want to use the web publication method you can just use a keyserver lookup:


Retrieval of keys from a keyserver

In order to verify or decrypt a message you need the public key of the sender.

Manually you can do this in this way:

gpg --recv-keys <names>

or even with:

gpg --search-keys <names>

and then selecting the number of the public key you want to add to your local keyring.

You might need to configure GnuPG to automatically do it for you every time a private key is not present in the local keyring.

This comes in very handy with Mutt, as you won't have to go and download and import a key manually in another terminal. In order to do this, add this line to your ~/.gnupg/gpg.conf file:

keyserver <keyserver address>
keyserver-options auto-key-retrieve

with the uri of your preferred keyserver. In this way every time a key is not present in your local keyring gnupg will try to fetch it from the keyserver specified in the gpg.conf file.

Verifying messages signatures

The %Z flag (status flag) in the $index_format tell you when a message is signed. If the message is signed (and it hasn't still been verified either it has a bad signature) a "s" character will appear in the corresponding line of the index, if the message signature has been verified then will appear a "S" character. In order to verify a message you need the corresponding public key of the sender being in your keyring, or setup gpg to automatically retrieve a corresponding key from a public keyserver (remember to setup the auto-key-retrieve keyserver-option as explained in the previous section).

In order to verify a message mutt runs the $pgp_verify_command and check the exit of the command.

The command in our case is specified as follows:

set pgp_verify_command="gpg --no-verbose --batch --output - --verify %s %f"

If $crypt_verify_sig is set to yes, mutt will run the pgp_verify_command on every opened message, and the output of this command will be displayed in the pager, before the message itself.

Verifying a message signature on the fly

You could be interested in verifying the signature of just a specific message. The following macros let you force the variable value of crypt_verify_sig to yes in order to get mutt verify the message, and then restore the previous value (you need mutt >= 1.5.12 with $my_variable support to get these macros working).

Please do not forget the "\" in the following macros code at the end of each line (or put all the text of each macro in one line).

macro index \Cv \
"<enter-command> set my_crypt_verify_sig=\$crypt_verify_sig<enter> \
<enter-command> set crypt_verify_sig=yes<enter> \
<display-message><enter-command> set crypt_verify_sig=\$my_crypt_verify_sig<enter>" \
 'Verify PGP signature and open the message'

macro pager \Cv \
"<exit><enter-command> set my_crypt_verify_sig=\$crypt_verify_sig<enter> \
<enter-command> set crypt_verify_sig=yes<enter> \
<display-message><enter-command> set crypt_verify_sig=\$my_crypt_verify_sig<enter>" \
 'Verify PGP signature'

Signing messages

$pgp_sign_as let you specify the uid to use when signing (since you can have different uids depending on the context). The corresponding public key will be extracted from your current keyring. You can set up some hook to customize the uid to use according to each particular situation.

You can automatically sign all outgoing messages setting

set pgp_autosign=yes

or simply selecting the pgp-menu (bound to "p") in the compose menu. You can use send-hook or folder-hook to setup the security criterion in a context dependant fashion.

Encrypting messages

To automatically encrypt messages to specific recipients use

send-hook . 'reset pgp_autoencrypt'
send-hook "!~l ~t onemail@example\\.org" "set crypt_autoencrypt crypt_autosign"
send-hook "!~l ~t another@example\\.org" "set crypt_autoencrypt crypt_autosign"

where the first global send-hook always resets crypt settings and a following matching, if any, send-hook sets crypt for that recipient. Note the double escaped backslash inside double quotes, "\\". The !~l pattern is to not activate encryption if the mail is also addressed to a known mailing list.

A handy script to generate such hooks for each active UID of keys in a public keyring can be retrieved as

Attachments (1)

Download all attachments as: .zip