Why?
Lately, I’ve been looking to distance myself from my smartphone. There are several reasons for this, including reducing distractions.
One of the things that I need my smartphone for is two-factor authentication. More specifically, my university requires the use of two-factor authentication for accounts. Until now, I have been using either the Microsoft Authenticator app or SMS codes to comply. However, I wanted to find a completely phone-free solution.
To be clear, I completely understand that using an authenticator app on a smartphone separate from your computer adds an extra layer of security. However, I’m not convinced that authenticating every session login with your phone is necessary if you follow good security practices such as using strong passphrases.
Note! I’m writing this post for informational purposes only. If you choose to implement something like this, please do so with caution and at your own risk.
Two-factor Authentication and Time-based One-Time Passwords
The idea with two-factor authentication is that in order to access their account a user must know something and have something. Typically, the “know something” part is covered by a passphrase, while the possession factor (“having something”) is often accounted for by an authenticator app on the user’s phone. A one-time password (OTP) generated by the app can serve as this possession factor.
Microsoft Authenticator utilizes a standard called Time-based One-Time Passwords (TOTP). The TOTP algorithm follows an open standard that you can read more about here. It uses symmetric key cryptography: the inputs include a shared key along with the system time. This way the two parties (server & client device) can separately calculate the passcode without network connectivity.
Now, let’s move on to how I replaced Microsoft Authenticator for one-time passwords and setup a solution for generating them on my laptop.
Using pass
for One-time Passwords
After some research, I decided to go with pass for this venture. It’s an open-source password manager licensed under the GPLv2. It uses GPG-encrypted files to store passwords and is extremely easy to use. In addition, TOTP support is available with an extension called pass-otp.
Installation
See the respective documentation pages for more details including installation options. Since I’m running macOS, I will install these using Homebrew:
brew install pass
brew install pass-otp
Setting Up the Password Store
Next, we need to create a GPG key for use with pass
. It’s crucial to use a strong passphrase for this key, distinct from the one you use to log in to the service requiring the OTP. Otherwise, you undermine the security benefits of OTPs altogether.
gpg --gen-key
After creating your key the pass
store can be initialized with it. First, obtain the fingerprint of your key with gpg --list-keys
. The fingerprint is a hexadecimal string with a length of 40.
pass init <key_fingerprint>
Adding the TOTP to the pass
Store
To use your pass
store for generating OTPs for your account you need to obtain a TOTP URI. It contains the secret that the TOTP algorithm needs in order to generate your OTPs.
In order to get your TOTP URI, you can follow the instructions provided by Microsoft here. When the guide tells you to open the Microsoft Authenticator on your phone just select Set up a different Authenticator app. Then when given a QR-code just select I can’t scan the bar code and it will reveal the TOTP secret for you as well as the organization name and your account email.
Using that information, form your TOTP URI following this format. If the OrganizationName contains spaces encode them with %20
instead.
otpauth://totp/<OrganizationName>:<Email>?secret=<MySecret>&issuer=<OrganizationName>
Now the URI can be inputted into your pass
store. Give your account a name. Here I’m using myaccount as an example:
pass otp insert myaccount
Now it’s time to test generating an OTP. You should be given a 6 digit OTP that you can use to verify your login.
pass otp myaccount
Lastly, I would make sure to make encrypted backups of both the pass
store and the GPG key. Also, I want to emphasize the importance of keeping the GPG key secure, as it is crucial for decrypting the OTP secrets. Ditching one’s phone for two-factor authentication means that extra care should be taken in keeping one’s laptop (or PC) secure, since there is no longer the extra layer of security of a separate physical device. Enabling full-disk encryption and using a strong passphrase is a good idea.
Automation
Alias
To make it even easier to generate your OTPs you could create an alias in your shell configuration file like this:
alias otp="pass otp -c myaccount"
But I want an even easier way to generate my OTPs.
AppleScript and Shortcuts (for macOS only, obviously)
I want to automate the process of opening a Terminal and running the OTP generation command using AppleScript and macOS Shortcuts. First, I will write some AppleScript to accomplish what I want.
If you’re unfamiliar with AppleScript, check out this guide for the fundamentals.
set myScript to "pass otp -c myaccount"
-- open new terminal instance
do shell script "open -na 'Terminal'"
-- get the pid for the instance
set pidList to do shell script "ps -e | grep 'Terminal' | awk '{print $1}' | sort -n"
set pidList to paragraphs of pidList
set recentPid to item -3 of pidList
-- generate OTP
tell application "Terminal"
do script myScript in front window
end tell
delay 1
-- wait for the GPG passphrase input
set isBusy to true
repeat until isBusy is false
tell application "Terminal"
set isBusy to busy of front window
end tell
delay 0.25
end repeat
-- close the terminal instance
do shell script "kill " & recentPid
The script is spawning opening a new Terminal instance, running the pass
command to generate and copy the OTP to my clipboard. It’s then waiting for that command to finish before killing the Terminal instance.
As the GPG passphrase must be written into the Terminal window to generate the OTP, a dynamic waiting time has to be used. Otherwise the window could be killed while I’m still typing the passphrase.
Creating a Shortcut
Now I can create a Shortcut that runs the AppleScript and either pin it to the Menu Bar or set a keyboard shortcut for it. To set this up, open the Shortcuts application, create a new shortcut, and select “Run AppleScript” as the action. Paste your script into the text box, then click the ℹ️ icon in the right sidebar to configure a keyboard shortcut or pin the shortcut to the Menu Bar.
Conclusion
Switching from Microsoft Authenticator to pass-otp
on my laptop has effectively reduced my reliance on a smartphone while ensuring compliance with my university’s 2FA requirements. Additionally, it saves me time every day.