Manage and secure your passwords across devices using Pass and GPG

Share on:
Keys on a table with 'Safety' written with Scrabble tiles

With security breaches happening left and right, the importance of having unique, strong passwords for each account has never been higher. However, remembering all these long passwords is nearly impossible for most people, and relying on your memory is impractical nevertheless.

This has turned password managers into a necessity in this internet age. While keeping a physical password book is still an option, it’s not as resilient nor as convenient as a proper password manager. Many password managers are closed source and your data is hosted on some company’s servers. While it may not be an issue, ultimately you don’t have control over the keys to your entire internet life. You must entrust these companies with storing and handling your data responsibly and securely.

This is where Pass comes in. It allows you to store your encrypted passwords using GPG and it’s all FOSS, which means you can see exactly how it works and you’re not at the mercy of any company. It’s simple to use and allows you to retain control over your data.

We will be using GPG, git and Pass itself to store our passwords in a secure, cross-platform solution. If you’re using another password manager, you will likely be able to migrate to Pass (see: “Migrating from other password managers”).

This guide was written and tested for Linux. If you’re on Mac, having Homebrew installed will be very helpful. It has not been tested on Windows or Mac, however it’s based on the available documentation. If you run into any issues not covered here, please do let me know at support@pvera.net.

Using GPG

Installation

In order to encrypt your passwords, we need to install GPG in order to generate a PGP key pair that will serve as our encryption key.

In this article, we will not be covering the whole public-private key encryption scheme, nor will we cover GPG signing. While this will leave you with a key pair that you could use for this, we won’t cover sharing and maintaining your public key either. For more on that, check out this wiki.

To install GPG:

  • Linux: Install the gnupg package using your package manager.
  • Windows: Install GPG4Win.
  • Mac: Install the gnupg package using Homebrew or install GPG Suite.

Generate key pair

In order to generate the key pair, open up a terminal and run:

$ gpg --full-gen-key

You will then be prompted to specify a few parameters for your key pair, as follows:

  1. For the kind of key, select RSA and RSA.
  2. For the key size, simply use the default, which should be either 2048 or 3072 bits long.
  3. For the expiration time, usually 1 year is a good option. It’s not necessary to generate new keys once they expire, you just need to extend the expiration date.
  4. Enter your name and email, when prompted. Leave the comment field blank.
  5. Verify that your information is correct.
  6. Use a strong passphrase. This will be the key to all your other passwords, so it needs to be a strong as possible. A very long password is preferred to a short one full of random characters. Essentially, the longer, the better. Write in some random words you can remember, add in some numbers, capitalization and maybe even special characters and you’ll be set.

Backup your keys

After generating your key pair, it’s a good idea to backup your private key in case you lose access to it for any reason. In order to do this, run the following command, where [email] is the email address that you entered in the previous step:

$ gpg --export-secret-keys --armor --output privkey.asc [email]

This will save your key to a file named privkey.asc. We will also generate a backup for the revocation certificate, which is used in case someone else gains access to your private key or if your key is lost definitely. In order to do this, run:

$ gpg --gen-revoke --armor --output revcert.asc [email]

This will save your revocation certificate to a file named revcert.asc. Be very careful with this file, as anyone with it can revoke your keys and it can’t be reverted. You can even print this if you like, in case you’d prefer not to keep it digitally. Whichever way you go with it, store these two files you just generated in a secure place, whether it be an encrypted drive or whatever else you prefer, away from your main system.

Export your keys to other devices

If you plan on using Pass on other devices, you will need to export your keys in order to decrypt the stored passwords. GPG gives you additional security by allowing you to export only the encryption subkey and not your master private key. This allows you to keep control over the master private key on your computer, which should hopefully be more secure, while keeping only subkeys on other devices.

In order to do this, find out the subkey you want to export by running:

$ gpg -K --with-subkey-fingerprint
/home/user/.gnupg/pubring.kbx
----------------------------------
sec   rsa3072 2020-12-10 [SC] [expires: 2021-12-10]
      195A4B9D57A9AB3A1038528A15289B28C5DA9496
uid           [ultimate] Full Name <email@example.com>
ssb   rsa3072 2020-12-10 [E] [expires: 2021-12-10]
      CC55ACAA661B6F17B2E8EFF9354192E9CDCDF07A

You should see an output similar to that one, perhaps with more entries in case you have more subkeys. Look for the one matching your name and email and copy the hexadecimal string under the ssb entry. This is the ID you need. In order to export it, run (note the “!” right after the ID, it’s important):

$ gpg -a --export-secret-subkeys [ID]! > subkey.gpg

This will save your subkey to a file named subkey.gpg. Copy this file over to whichever device you want to use it on and import it by running on the new device:

$ gpg --import subkey.gpg

You can go further and use a different passphrase for this subkey on another device. This makes it so that in case the subkey’s passphrase is compromised, your master key’s passphrase is still uncompromised. If you wish to do this, on the new device run:

$ gpg --edit-key [email]
> passwd
> save

After you type passwd, you will be prompted to select the new passphrase. Once you’ve set it and hit save, it will warn you that the password wasn’t changed because the master key was unavailable. However, this refers to the master key’s passphrase; the subkey’s password was changed. You can therefore simply ignore the message.

Extending the expiration date

Further down the line, you will have to renew your keys once they approach the expiration date. This is quite simple, but you will need the master key, this cannot be done on devices that only have a subkey. To do this, run:

$ gpg --edit-key [email]
> expire

Set a new expiration day as prompted. You will have to do this for the subkey as well. In order to do it, run:

> key 1
> expire

Once you’ve set the new expiration date for both keys, save your changes by running:

> save

You can now export your subkey as described in the previous subsection. It’s not necessary to backup your master private key again, as it can still be renewed even if it’s long expired.

Pass

Migrating from other password managers

If you’re using another password manager like 1Password, Keepass, Lastpass and others, check out the “Migrating to pass” section at the bottom of this page.

Installation

In order to use Pass as your password manager, there are two options for the desktop, pass and QtPass.

  • pass, the CLI version, is available for Linux and Mac. You can install the pass package, using your package manager, or Homebrew on Mac.
  • QtPass, the GUI version, is available on Linux, Windows and Mac. Download the qtpass package from your package manager on Linux, or from here on Windows and Mac.

Additionally, we’ll be using git to track changes and sync the password database across devices, so make sure you have it installed.

  • On Linux, you can install the git package with your package manager.
  • On Mac, you can get it by installing Xcode or by installing the git package with Homebrew. You can also get it here.
  • On Windows, you can get it here. Check this out if you need help installing it.

Once you have Pass set up, there are both Android and iOS apps you can use to access your passwords.

Set up Git

To set up your remote git repository, you could either host it yourself, or if you can’t do this, you can create an account on Gitlab and create the repository there. I’d strongly recommend hosting the git repository yourself.

Whichever way you go, note the remote git repository URL, we will be needing it shortly. Make sure you configure git by running:

$ git config --global user.email "email@example.com"
$ git config --global user.name "Full Name"

Strictly speaking, you don’t need to use the same name and email as you did for the key pair, but doing so will simplify things. You’ll need to run these two lines on all the computers that you want to use with Pass. It’s not necessary on mobile.

If you decide to go with a local git repository, keep reading. Otherwise, you can skip to “Using Gitlab”.

Using a local git repository

In order to host your own git server, you’ll need to have git installed on said computer. If this is the same computer as the one you will have Pass installed on, then you will already have git installed.

I’d recommend adding a user only for the git server on your computer. If you’re on Mac, follow this guide and add a standard user. On Linux, run:

$ sudo useradd -m git
$ sudo passwd git

This will add a new user named git and set its password. You can name it whatever you want, but we’ll call it git for simplicity.

Make sure you have enabled SSH on the computer that will serve as your git server. If you’re on Mac, follow this guide. Unless you use SSH for something else, it’s best to only allow the git user to SSH in.

Now, login into your git user. You can do this in a terminal by typing:

$ su - git

You’ll now be in the home directory as your git user. Here, you can create the directories for new repositories. We will create the repository for the password store by running the following:

$ mkdir ~/password-store.git
$ cd ~/password-store.git
$ git init --bare

This will create an empty repository, ready to be synced to. This is as much as you need to set up git on the server, but there’s still additional configuration needed for SSH.

You will need to set up your server with a static IP address. You can follow this guide for Linux or this guide for Mac on how to do this.

If you will only use the git server on your local network, meaning devices will only be able to sync to the password store when they’re on the same network as the server, you won’t need any further configuration. The URL you will need for the next section will look something like git@192.168.1.10:/home/git/password-store.git, assuming your username is set as git. Your IP will probably be different, use the one you just set. On Mac, the path will look more like /Users/git/password-store.git.

If you won’t open it up to the internet, you can skip ahead to setting up Pass CLI or to setting up QtPass.

If you plan on allowing internet access, you will need to get a domain and forward the SSH port to your computer. You can do so by following this section of my static website, where instead of forwarding ports 80 and 443, you will need to forward port 22.

Before doing this, I strongly recommend to install Fail2Ban, since you will have people trying to brute-force your password. This is also why it’s very important to have a strong password. If you set up a weak one, now is the time to change it.

To install Fail2Ban, install the fail2ban package using your package manager, or from Homebrew on a Mac. The configuration should work out of the box for SSH.

On Mac, make sure everything is set up as shown here. Your jail.conf file should have the sshd jail enabled. Also, make sure the log file specified in the jail.conf file exists. If not, create it.

On Linux, simply run:

$ sudo systemctl start fail2ban
$ sudo systemctl enable fail2ban

On Mac, to start it, run:

$ sudo fail2ban-client start

To verify that it’s running on either Linux or Mac, run:

$ fail2ban-client status

Be careful when trying to SSH in. Entering the wrong password a few times will get you banned for some time. If you messed up, look here on how to unban an IP address.

You could go further and disable password-authentication for SSH. This means you will have to generate SSH keys and distribute them to all your devices. Using key-based authentication is recommended, however, it may not be possible depending on your setup.

If you decide to go this route, you can follow this guide on generating your SSH keys. In order to disable password authentication, modify your SSH config (typically /etc/ssh/sshd_config) and set this line as such:

PasswordAuthentication no

Restart your SSH server to load the changes.

Finally, if you set up your domain and port forwarding correctly, you should be able to access your server at git@yourdomain.tld. The remote URL you will need in the following sections will look something like git@yourdomain.tld:/home/git/password-store.git. This assumes you set the new user as git. On Mac, the path will look more like /Users/git/password-store.git.

You can now skip ahead to setting up Pass CLI or to setting up QtPass.

Using Gitlab

If you decide to use Gitlab, the process is pretty simple.

  1. Create your account.
  2. Go here and click on the green “New Project” button at the top right corner.
  3. Select “Create blank project”.
  4. Name your project to whatever you want. Make sure it’s set to private and do not tick the “initialize with README” checkbox.
  5. Click on “Create project”.
  6. In order to access your repository, you can use either SSH (recommended) or HTTPS:
    • If you wish to use SSH to access your Gitlab repository, follow this guide to generate the SSH keys and follow this guide to add them to your Gitlab account.
    • If you decide to use HTTPS, you will have to enter your Gitlab username and password every time you want to upload something.
  7. Save the appropriate URL under the blue “Clone” button at the top right of the page (SSH or HTTPS). This is the URL you’ll need for the remote repository next.

If you decide to use Pass CLI, keep on reading. Otherwise, skip to “Using QtPass”.

Using Pass CLI

Once you have pass installed, to initialize your password database, run the following, where [email] is the email used to set up your GPG keys:

$ pass init [email]

This will create your password database. To initialize a git repository for your passwords, run:

$ pass git init

In order to configure the remote repository for git, run:

$ pass git remote add origin git@gitlab.com:username/reponame.git

This is the link you got in the last section. Your link will look similar if you used Gitlab, replacing username with your Gitlab username and reponame with whatever name you gave to your repository.

If you used a local repository, you’ll have to use your domain instead of gitlab.com (or the computer’s local IP address, if you didn’t open it up to the internet). In either case, you’ll use the computer’s user instead of the git before the URL or IP address.

To insert new passwords, run:

$ pass insert example.com/account/username

This follows a directory structure, where it’s common to do write the website or host, followed by what it is and finally the actual username. You can do whatever you want, however it’s best to find a tree structure you like and stick to it in order to facilitate using the tool.

Pass can also generate passwords, if you prefer, by running:

$ pass generate example.com/account/username [length]

Where you can substitute [length] by how long you want your password to be.

In order to upload your password store for the first time to the git repository, run:

$ pass git push -u --all

To upload normally afterwards, simply run:

$ pass git push

To sync your password store with the repository, run:

$ pass git pull

I recommend always running this after you’ve uploaded anything with any other device to the password store in order to avoid any conflicts. Similarly, if you change anything on your device, always upload your changes immediately.

In order to get a stored password, simply type:

$ pass example.com/account/username

This will print the password to your terminal. If you prefer to have it temporarily copied to your clipboard, run:

$ pass -c example.com/account/username

You can use tab autocomplete for the paths.

For more commands, like deleting, renaming, moving or copying passwords, run:

$ pass help

Using QtPass

QtPass is simpler to use, but you may run into OS-specific pitfalls. If you have any issues, check out the QtPass FAQ for help.

To set up your GPG key pair for encryption, click on the icon shown in the picture and select the key you generated.

QtPass GPG key selection icon

Click to select your key

In order to add passwords to your password database, you can click on the new folder icon to create a directory, and you can click on the new file icon to insert a password. This usually follows a tree structure, where the top directory will be a website or host, then the directory inside will be what you’re storing a password for and the third level of directory will be the password itself, usually named after the username. For example:

  • example.com
    • account
      • username (this is your password file)

You can do whatever you want, however it’s best to find a tree structure you like and stick to it in order to facilitate using the tool.

In order to set up git with our password store, we will need to create the directory first. To do this, just add any password you like, as described above. Once you have done this, click on the settings icon (the right-most icon) and go to the “Profiles” tab. At the bottom, it will show the path to your password store.

QtPass path to password store in the settings panel, 'Profiles' tab

Get the path to your password store here

Go to this directory on a terminal (or using Git Bash, if you’re on Windows) and run:

$ git init --bare
$ git add *
$ git commit -m "Initial commit"
$ git remote add origin git@gitlab.com:username/reponame.git

This is the link you got in the last section. Your link will look similar if you used Gitlab, replacing username with your Gitlab username and reponame with whatever name you gave to your repository.

If you used a local repository, you’ll have to use your domain instead of gitlab.com (or the computer’s local IP address, if you didn’t open it up to the internet). In either case, you’ll use the computer’s user instead of the git before the URL or IP address. To upload the repository to the remote location, run:

$ git push -u -all

Now, go back to QtPass and enable git support by clicking on the settings icon and on the “Settings” tab, make sure to check all the boxes under the “Git” section. This will make sure your password store gets updated automatically.

QtPass settings panel, showing Git options, among others

Check all the boxes under ‘Git’

In this panel, you can also set how long you want the default length for generated passwords to be. When you insert a new password, if you decide to click on “Generate”, you can change this to whatever value you prefer. You can also set the clipboard behavior at the top if you want passwords to be copied to your clipboard instead of displaying it in a window, as well as a timer to clear the password from your clipboard.

To see or copy a password, simply click on the file you want and enter your GPG key password when prompted. You can also delete and edit passwords using the icons at the top or by right clicking on them.

Conclusion

You should have a fully working setup that will work on Linux, Windows, Mac, Android and iOS. This also works on BSD, the steps are very similar to Linux’s. Reference online documentation if you have any issues. Other than renewing your GPG keys, it requires no further maintenance and will work as long as you want it to. And the best part of it all: it’s free!