Skip to content
0

gpg

Following is the configuration of my ~/.config/isyncrc file:

# twine ========================================================
# 1. Configure the remote server
IMAPAccount twine
Host twineintlcom.securemail.hk
User alowree@twineintl.com
# Works on macOS only
# PassCmd "security find-generic-password -a 'alowree@twineintl.com' -s 'neomutt-twine' -w"
# Works on both macOS and Arch Linux
PassCmd "pass Email/alowree@twineintl.com"
Port 993
TLSType IMAPS
AuthMechs PLAIN
# SystemCertificates no
# CertificateFile ~/.maildir/certificates/root-certificates.pem

# 2. Configure the remote store
IMAPStore twine-remote
Account twine

# 3. Configure the local mail store
MaildirStore twine-local
Path ~/.maildir/twine/
Inbox ~/.maildir/twine/INBOX
SubFolders Verbatim

# 4. Connect them with a channel
# Channel connecting <acount-name>-remote to <acount-name>-local
Channel twine
Far :twine-remote:
Near :twine-local:
Patterns *
Sync All
Expunge Both
Create Near
Remove Near
SyncState *
CopyArrivalDate yes
ExpireUnread yes
# ==============================================================

As you can see, currently I use the app keychain to manage passwords on macOS, and I use it inside the isyncrc config file to retrieve password for my primary email account. Now that I have another newly installed Arch Linux, and I intend to converge my Neomutt configurations into the same one set, which is "gpg+pass" based and can be fully shared between macOS and Arch Linux, so that I don't have to maintain two different sets of configurations between the two operating systems.

Generate one detailed tutorial to introduce GPG and some use cases, then another tutorial about the unix password manager pass. Then combine the two for the actually implementation inside my neomuttrc configuration files. So there are going to be three parts in total, GPG, pass, and then the combination of the two. In order to make the tutorials full of details, your first output should be focus on GPG only.

This is an excellent plan. Moving to a pass + GPG setup is the definitive way to have a unified, secure, and scriptable configuration across macOS and Arch Linux. Since pass is essentially a wrapper for GPG, we must start by getting GPG configured perfectly on both systems.

Here is Part 1 of your tutorial, focused solely on GPG.

1.1 What is GPG and Why is it the Right Choice?

GnuPG (GPG) is a free implementation of the OpenPGP standard. At its core, it is a cryptography tool that allows for secure communication and data storage.

For your specific use case (converging NeoMutt configs), we care about two specific features:

  1. Asymmetric Encryption: GPG uses a Public Key to encrypt data (locking it) and a Private Key to decrypt it (unlocking it). This means you can safely store an encrypted file in your Dropbox or GitHub repo because only your Private Key can unlock it.
  2. The Agent: GPG comes with a background service called gpg-agent. It caches your passphrase for a set amount of time. Once you unlock your key, pass and mbsync can retrieve passwords without prompting you every single time.

1.2 Installation (macOS vs. Arch Linux)

We need the same version of GPG on both systems to avoid compatibility headaches.

On Arch Linux: Open a terminal and run:

bash
sudo pacman -S gnupg

On macOS: You have two options. Option A is the standard command line tool (via Homebrew). Option B is the GPG Suite (which includes a GUI key manager and better macOS integration). I strongly recommend Option B for macOS users because it handles passphrase caching in the login keychain more gracefully.

  • Option A (Homebrew):

    bash
    brew install gnupg
  • Option B (GPG Suite - Recommended):

    bash
    brew install --cask gpg-suite

    Note: If you use GPG Suite, you will use their GUI to manage keys, but the terminal commands remain exactly the same.

I took Option A on my macOS machine, because I felt comfortable working inside the terminal and wanted to experience the very basic gnupg utiliy in the first place.

1.3 Creating Your Master Key Pair

We will create a key that never expires. While security purists prefer expiration, for email setup maintenance, a non-expiring key simplifies the process (provided you keep it safe).

Run the following command on either macOS or Arch (it is identical):

bash
gpg --full-generate-key

You will be guided through a prompt. Here is exactly what to choose for email compatibility:

  1. Kind of key: Select 1 (RSA and RSA) (default).
  2. Keysize: Enter 4096. (While pass works with 2048, 4096 is the modern standard for email encryption).
  3. Expiration: Enter 0 (Key does not expire).
  4. Real name: Enter your full name (e.g., Alowree XU).
  5. Email address: Enter alowree@twineintl.com (This must match the email in your isyncrc).
  6. Comment: (Optional, e.g., Email Key).

Finally, you will be asked for a passphrase.

  • Security: This is the master key to your digital identity. Make it long and strong.
  • Usability: Because we will cache this, you will only type it once per login session.

1.4 Finding Your Key ID

pass doesn't care about your name; it cares about a specific ID. List your keys to find it.

bash
gpg --list-secret-keys --keyid-format LONG

You will see output similar to this:

sec   rsa4096/AAAAAAAAAAAAAAAA 2024-01-01 [SC]
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid                 [ultimate] Alex Lowree <alowree@twineintl.com>
ssb   rsa4096/BBBBBBBBBBBBBBBB 2024-01-01 [E]

The string next to rsa4096/ is your Key ID. In this example, it is AAAAAAAAAAAAAAAA (the last 16 characters of the fingerprint).

Copy this Key ID. You will need it to initialize pass in Part 2.

1.5 The "Headless" Challenge (Crucial for Arch Linux)

There is a common trap on Arch Linux (and sometimes macOS) where GPG cannot find your terminal to ask for the passphrase.

If you run a command and get gpg: decryption failed: No secret key or Inappropriate ioctl for device, your GPG_TTY variable is not set.

The Fix: Add this line to your shell config file (~/.zshrc if you use Zsh, or ~/.bashrc for Bash):

bash
export GPG_TTY=$(tty)

After adding it, restart your terminal or run source ~/.zshrc.

1.6 Configuring the Agent (Killing the Pop-ups)

The goal is to enter your passphrase once when you log in, not every time mbsync runs.

Create the configuration file ~/.gnupg/gpg-agent.conf:

bash
nano ~/.gnupg/gpg-agent.conf

Paste these settings:

# How long (in seconds) the password stays in memory after last use
default-cache-ttl 28800

# Max time the password stays in memory regardless of activity
max-cache-ttl 86400

# The program that asks for the password
pinentry-program /usr/bin/pinentry-tty
  • For macOS (GPG Suite): Change the last line to pinentry-program /usr/local/bin/pinentry-mac to get a native Mac dialog box.
  • For Arch: pinentry-tty works perfectly in the terminal.

Restart the Agent:

bash
gpgconf --kill gpg-agent

1.7 Testing Your Setup

Before moving to pass, let's ensure the encryption works.

  1. Export your Public Key (You don't need this now, but it validates the key):

    bash
    gpg --export --armor alowree@twineintl.com > my-public-key.asc
  2. Test Encryption/Decryption:

    bash
    echo "Secret testing" > test.txt
    gpg --encrypt --recipient alowree@twineintl.com test.txt
    rm test.txt
    gpg --decrypt test.txt.gpg

    If you see Secret testing printed to the screen, your GPG is configured perfectly for Arch Linux, macOS, and your upcoming pass setup.

In Part 2, we will take this GPG key and use it to initialize pass, migrating your Keychain password into a simple, syncable file structure.


Welcome to the first part of your cross-OS convergence setup. Moving away from platform-specific tools like macOS Keychain and toward a unified command-line architecture gives you immense flexibility.

Before we can use pass to feed your passwords to isync/mbsync and neomutt, we need a firm foundation in GnuPG (Gnu Privacy Guard). GPG handles the actual cryptographic heavy lifting (encryption, decryption, and key management) under the hood.

1. What is GPG and Asymmetric Cryptography?

Unlike standard password-based encryption (symmetric encryption) where the same key locks and unlocks data, GPG is predominantly based on asymmetric cryptography (public-key cryptography).

  • The Public Key: Think of this as an open padlock. You can hand copies of it to anyone. They use it to encrypt data meant for you or to verify things signed by you.
  • The Private Key: This is the physical key that opens that padlock. Never share this. You protect it with a strong passphrase, and it is used to decrypt data or sign data.

For your specific use case (managing local passwords), you will use your Public Key to lock (encrypt) your email passwords, and your Private Key to unlock (decrypt) them whenever neomutt or mbsync requests them.

2. Setting Up GPG on macOS and Arch Linux

Because we are aiming for a unified configuration, we want to install GPG on both environments so that they behave identically.

Installation

  • On Arch Linux:
bash
  sudo pacman -S gnupg pinentry
  • On macOS (via Homebrew):
bash
brew install gnupg pinentry-mac

Generating Your Key Pair

Run the following command on either machine (we will export it to the other later):

bash
gpg --full-generate-key

When prompted, choose the following recommended options:

  1. Kind of key: Select (1) RSA and RSA (default) or (9) ECC (Elliptic Curve) if you prefer modern cryptography. RSA (3072 or 4096 bits) is widely supported.
  2. Keysize: If you chose RSA, type 4096.
  3. Validity: Choose 0 (key does not expire) for personal password storage convenience, or set a realistic timeline (e.g., 2y).
  4. User ID Details: Enter your real name and the email address matching your configuration (alowree@twineintl.com).
  5. Passphrase: Enter a strong passphrase. Remember this well. This passphrase will be the master key to unlocking all your passwords.

3. The Magic Component: gpg-agent & Pinentry

If you had to type your long master GPG passphrase every single time mbsync ran a background sync, you would go crazy. That's where gpg-agent comes into play. It caches your decrypted private key in memory so you only have to type your password once per session.

To ensure seamless prompting in both desktop graphical environments and headless TUI terminal sessions, we need to configure gpg-agent.

Create or edit your gpg-agent configuration file:

bash
nano ~/.gnupg/gpg-agent.conf

Add the following lines to optimize caching and pinpoint your entry program:

ini
# Cache the passphrase for 1 day (86400 seconds) after last use
default-cache-ttl 86400
max-cache-ttl 86400

# Tell GPG which pinentry program to default to
# (We will use a smart trick to handle macOS vs Arch automatically)

Dealing with Cross-OS Pinentry

Because macOS benefits from a native graphical popup (pinentry-mac) and Arch Linux might use a terminal screen (pinentry-curses) or a Linux GUI popup (pinentry-gnome3), it helps to let GPG adapt, or fall back dynamically.

On macOS, ensure your ~/.gnupg/gpg-agent.conf links explicitly to homebrew's variant if it doesn't pop up:

ini
pinentry-program /opt/homebrew/bin/pinentry-mac

On Arch Linux, it usually defaults cleanly to standard terminal or desktop prompts. If you run into issues on headless environments, adding pinentry-program /usr/bin/pinentry-curses fixes it.

After editing the configuration, reload the agent:

bash
gpg-connect-agent reloadagent /bye

4. Key Syncing: Moving GPG to your second OS

Since you generated your key pair on Machine A, you must securely copy it to Machine B to achieve complete convergence.

Step 1: Export from Machine A

Find your Key ID first:

bash
gpg --list-secret-keys --keyid-format=long

Look for the hex string on the sec line (e.g., 3AA5C34371567BD2). Export both your public and private keys to files:

bash
gpg --export -a "alowree@twineintl.com" > public.key
gpg --export-secret-keys -a "alowree@twineintl.com" > private.key

Step 2: Transfer Files Securely

Move public.key and private.key over to your other machine using a secure medium (e.g., scp, a thumb drive, or an encrypted local transfer).

Step 3: Import on Machine B

On the second machine, pull the keys into your local GPG keyring:

bash
gpg --import public.key
gpg --import private.key

Step 4: Establish Trust

By default, GPG treats imported keys with suspicion. You must explicitly mark your own key as trusted on the new machine:

bash
gpg --edit-key "alowree@twineintl.com"

You will enter an interactive GPG prompt. Type trust, select option 5 (I trust ultimately), confirm with y, and then type quit.

5. Essential Verification Commands

Before moving on to Part 2 (where we install pass), let's make sure your GPG setup is working exactly as intended by simulating basic text encryption and decryption.

  • To Encrypt a Test String:
bash
echo "SecretEmailPassword123" | gpg -e -r "alowree@twineintl.com" > test.gpg
  • To Decrypt a Test String:
bash
gpg -d test.gpg

If the second command prints SecretEmailPassword123 cleanly (prompting you via a popup window for your passphrase the first time, and succeeding instantly without a prompt the second time), your GPG configuration is flawlessly established.

This completes the first building block. Let me know when you are ready, and we will move to Part 2: Configuring the standard UNIX password manager (pass) using this GPG key.

最近更新