Using the same password for online accounts is a bad idea if you are doing this please stop it and try to use a password manager, even if you are using a long password, because if one site got compromised due to some hack, your password is exposed, and you need to change passwords to all accounts again. There are many options out there in the below post. I will suggest a few options which are free.

Password Strength (https://xkcd.com/936/)

gpg

gpg - Using plain old PGP/GPG. I would suggest going through this post, which covers the basics of cryptography and steps to set up gpg.

To generate random passwords, you can use either OpenSSL or gpg
Generate random string of length 14
Using openssl

openssl rand -base64 14

Using gpg

gpg --gen-random -a 0 14

You can use Vim to configure with gpg; refer this section. Let’s say you have test.com site login details. Now you can create a file with extension .gpg or .asc (test.com.gpg) and open it with Vim, you will be prompted to select recipients (mostly here; you will choose your email) and you can enter your username and password of test.com in that file and close the file.

vi /tmp/test.com.gpg
username
password
secure questions

If you try to peek the contents of test.com.gpg, then you will text like below

more /tmp/test.com.gpg
-----BEGIN PGP MESSAGE-----

hQGMAwAAAAAAAAAAAQwAm9jDnYO6y9xGAfsuaHqbHs/oIa9H+anq6l9cStiGIEwW
gYXTGUHFbm7roUUfvMiDUgg5IaJPx7TrHM4R8BrHDLr//BqCiIgAgXFxqlxdOmen
XGzcPHaW2snMW4RcEnQqcsE15envlMFf+BfBFpfF5sL9yWB6jvQEM578nklFMc+e
CtkKN3ftWun8JSptaE0mVxgM3D01THkvZ+aqYIoO+8pifmZD3Mvg0szAX2kyDxjR
8UaDMki8bL3BKr14/9aA2ANJO17xpDyAxzwJ6LEGCg0nxlPZ0aylkzqO2Kxg4uY3
SXcJ0hd0R1dRzoMlg1/GqyWw1NU49goCCD/LFwaszx/abDO6FDxHAn48edKnVskL
sxWfnQ8q3rEgtkKSF6CVJcTqGoOs2w9gFh/Gfh4FNdOOCPPru7mu4346WhVY4PrW
gvJDwpFYJveuYNdDb7pZMO7W7j9hpgw+/PSk1cfw0g9aYe+RtTwF8YidHMW9JYg9
I3xsMbd02MePsAa4vGsy0kABy94+NnKP2rTPNtfetfVoPmKSOy2lXydpk8It9I8s
mcNzx2Z3X68HiMl+GaOfNkCLqmvNI9POn7N0EVo2Tw42
=sswm
-----END PGP MESSAGE-----

If you want to achieve the above without Vim, you can use any editor to create a file with the site name (ex - test.com). Please write down the username and password and any text you want to keep, save it

more /tmp/test.com
username
password
secure questions

and then use the below command to encrypt

cat /tmp/test.com | gpg -ae --recipient your-mail@mail.com > /tmp/test.com.gpg

and to decrypt use below

cat /tmp/test.com.gpg| gpg -dq

make sure you delete the /tmp/test.com file, which has unencrypted text.
The above method is using asymmetric key encryption. You can also symmetric encryption
To encrypt

cat /tmp/test.com | gpg -ac --cipher-algo AES256 > /tmp/test.com.gpg

You will be prompted for a password. and to decrypt use below, you will be prompted for a password.

cat /tmp/test.com.gpg| gpg -dq

Usually, you will keep all these files in a folder and keep it in a secure location and make a backup of it in a private GitHub repository.

Many scripts are available, so you don’t need to remember the above commands. You can use drduh/Purse to store passwords using GPG asymmetric encryption, or you can use drduh/pwd.sh to store passwords using GPG symmetric encryption.

OTP/2FA

You can also maintain TOTP(Time-based One-Time Password) using gpg and oathtool. Most of the sites, when enrolling for two-factor authentication, would provide both text code and QR code; you can copy the text code and use oathtool to get OTP like below

oathtool --base32 --totp <OTP-SECRET>
Ex:
oathtool --totp --base32 qmli3dwqm53vl7fy

If they provided only QR code, you could get text code using a QR code scanner. You can take a screenshot and use a tool like zbarimg to get text code.

zbarimg qr-screen-shot.png

Now you should keep that text code encrypted, and you can encrypt using either asymmetric or symmetric way to store the OTP secrets. You can also use some script like below to maintain totp secrets. Note: Below script uses symmetric encrypton

#!/bin/bash

set -e
set -o pipefail

SOURCE_DIR=~/.config/2fa

function init() {
    mkdir -p $SOURCE_DIR
    chmod 0700 $SOURCE_DIR

    if ! hash gpg 2>/dev/null ; then
        echo "Please ensure that GnuPG is installed!"
        exit 1
    fi
    if ! hash oathtool 2>/dev/null ; then
        echo "Please ensure that oathtool is installed!"
        exit 2
    fi
}

function add_key() {
    echo "Adding a new key"
    if [ "x$1" != "x" ] ; then
        identifier=$1
    else
        echo "What's the identifier?"
        read -r identifier
    fi
    echo "What's the secret?"
    read -r secret
    echo "$secret" | gpg --quiet --symmetric --out "$SOURCE_DIR/$identifier"
}

function get_totp() {
    if [ "x$1" != "x" ] ; then
        identifier=$1
    else
        echo "What's the identifier?"
        read -r identifier
    fi
    secret="$(gpg --quiet < "$SOURCE_DIR/$identifier")"
    oathtool --base32 --totp "$secret"
}

function get_secret() {
    if [ "x$1" != "x" ] ; then
        identifier=$1
    else
        echo "What's the identifier?"
        read -r identifier
    fi
    secret="$(gpg --quiet < "$SOURCE_DIR/$identifier")"
    echo "$secret"
}

function list() {
    ls -1 "$SOURCE_DIR"
}

function help() {
    echo "Setup a new TOTP account or generate a new TOTP token from an existing account."
    echo
    echo "Usage: totp.sh [--add|--list|--totp] [IDENTIFIER]"
    echo
    echo -e "--add     Will ask for an identifier (i.e. 'google', 'slack', ...) and\\n" \
            "         then for the secret provided by the service provider."
    echo -e "--list    Will list all available identifiers."
    echo -e "--show    Will show secret for given identifier."
    echo -e "--totp    Will ask for an identifier (i.e. 'google', 'slack', ...) and\\n" \
            "         then return the TOTP token."
}

init

case $1 in
    --add)
        add_key "$2"
        ;;
    --list)
        list
        ;;
    --totp)
        get_totp "$2"
        ;;
    --show)
        get_secret "$2"
        ;;
    *)
        help
esac

Usage: To add totp

~/totp --add test

To show secret

~/totp --show test

To get OTP code

~/totp --totp test

pass

pass made the above process easy, so you don’t need to do the above steps to store your data manually. pass is available in macOS through brew and in Linux. Below are the steps you can follow to create a new password store.

  • Initialize password store pass init <YOUR-GPG-ID>
  • Initialize git pass git init.
  • To generate password pass generate test.com 15
  • To insert username and password pass insert -m test.com
  • To push to remote git pass git push origin main
  • To list all sites pass
  • To show the password of the site - pass test.com
  • Refer this manual page for more options.

To use existing password store

  • Clone the existing password store git clone git@github.com:username/passwordstore.git ~/.password-store

OTP/2FA

pass-otp is an extension to pass, which gives option to manage OTP tokens.

pass otp insert test.com
Enter otpauth:// URI for test.com:
Retype otpauth:// URI for test.com:

OR
zbarimg -q --raw google-qrcode.png | pass otp append test.com

To get OTP code

$ pass otp test.com
698816

# to copy to clipboard
pass -c otp test.com

Browser plugins

browserpass is available for all major browsers which will read the passwords from $HOME/.password-store. You must need to install browserpass-native.

Mobile Apps

There is an Andriod app Android-Password-Store. And for iOS passforios.

For Andriod-Password-Store, you can use your gpg keys in OpenKeyChain to pull your private GitHub repo like below. Please make sure you have an SSH authentication key in your subkeys; refer to this section on how to do it.

Andriod Password Store/OpenKeyChain might not work if you have throw-keyids in ~/.gnupg/gpg.conf. Refer this github issue .You can run below script

mkdir /tmp/tempst
TEMP_DIR=/tmp/tempst
GPG=$(which gpg)
PASSWORD_STORE_DIR=${PASSWORD_STORE_DIR:=$HOME/.password-store}
for file in $(find ${PASSWORD_STORE_DIR} -iname '*.gpg'); do
  echo "Processing ${file}"
  temp_file="${TEMP_DIR}/${file##*/}"
  ${GPG} -q --decrypt "${file}" | ${GPG} --no-throw-keyids --encrypt -r $KEYID --output "${temp_file}"
  mv -f "${temp_file}" "${file}"
done
pass git commit -a -m "Adding key ids (i.e. gpg --no-throw-keyids)"
pass git push origin master

And you need to make sure that you have export PASSWORD_STORE_GPG_OPTS='--no-throw-keyids' in your shell rc file so that future encryption works.

KeePassXC

Another option would be to use KeePassXC; it is available on all platforms. It uses AES256 symmetric to store the database.

  • Create a new database and choose some secure location to save the database.
  • Configure timeouts on how long to keep the password in the clipboard and when to lock the database.
  • Configure keyboard shortcut to fill the username and entry.
  • Click on “+” sign for “Add a new Entry” and you can add an entry like below. You can click on the square box to generate a random password.
  • You can go to the “Advanced” tab and add attachments to this entry.
  • You can use the select icon for the entry in the “Icon” tab.
  • You can also store your ssh private key as an attachment in an entry and use that to add to the agent like below. First, enable ssh in application settings.

And then entry=>SSH agent select below options and in private key select that private key attachment.

  • You can also enable 2-factor authentication using a file or Yubikey in Database Security.
  • You can use KeeShare to share the group (folder) with another user, so the passwords are synced bi-directional
  • You can download the favicon of all websites in your database.
  • You can use Database Reports to check for weak passwords.

OTP/2FA

KeePassXC supports storing OTP secrets. In Entry=>Advanced=>Additional attributes=>Add and then rename the attribute as “otp” and then give value as otpauth://totp/test.com:username?secret=ABCEDADFASDFA&period=30&digits=6&issuer=test.com. Then you should be able to copy TOTP like below.

Browser plugins

KeePassXC is available in all browser plugins. You can enable them in application settings.

Mobile Apps

Refer KeePassXC User Guide for detailed documentation.

Bitwarden

We discussed only offline password managers where all the files have resided on your laptop. The advantage of offline password managers are that they are more secure since the database is with you, and you can store it where ever you want. The disadvantage is there is a manual configuration, and you need to make sure that your database is not deleted. With online password managers, most of the functionality is available out of the box, like apps and plugins.

How the data is stored in Bitwarden?

Bitwarden always encrypts and/or hashes your data on your local device before anything is sent to cloud servers for storage. Bitwarden servers are only used for storing encrypted data. - https://bitwarden.com/help/article/data-storage/

Bitwarden vault can be accessed through web access and Desktop apps

OTP/2FA

With Bitwarden, you can store the OTP secrets and can generate TOTP codes; please refer to Bitwarden TOTP

Browser plugins

Bitwarden has extensions for all browsers please refer plugins

Mobile Apps

Bitwarden has apps for Andriod and iOS; please refer to Mobile apps

One important feature would be Bitwarden send, which helps transfer sensitive information to anyone securely and temporarily.; this can be useful to share any sensitive data to a friend or colleague.

You can also self-host Bitwarden so that data is in your server; you can follow the steps listed. here, if you are using DigitalOcean you can deploy a Bitwarden droplet

Conclusion

I think this post gave some insights on how to store your passwords or any secure data using offline and online password managers.

– RC