negative zero

Using Duo 2FA without the app

2022 May 16

[2fa] [tech] [tutorial]

My future school uses Duo for two-factor authentication. Duo expects you to use its smartphone app. I don't have a smartphone, and even if I did, I have an ideological objection to using Duo's non-free app.

So let's look at how to avoid the Duo app.

Hardware token

Duo supports hardware U2F devices. I actually have a Yubikey, but I've pretty much never used it. It didn't work when I tried to set up Duo with my Yubikey. I probably did something wrong and just need to set it up properly, but that's a project for later me.

Update: I registered my Yubikey with a different computer. It was very easy and worked without issue. The reason it didn't work before was because I was trying to set it up in a Qubes VM, and I couldn't connect the USB device to the VM.


You can use a program like the duo-hotp Python script to get your Duo HOTP secrets.


1. Install dependencies

Required dependencies:

On Fedora

sudo dnf install python3-pyotp python3-docopt

On Arch

sudo pacman -S python-pyotp python-docopt

On Debian

sudo apt install python3-pyotp python3-docopt

2. Download

You can git clone or just save

3. Set up the Duo side

In your browser, start the Duo setup. It will ask which type of device you're adding. Select Tablet.

Select Tablet as the type of device to be added.

Duo setup will ask what type of tablet you're adding. Select Android.

Select Android as the type of tablet.

Duo setup will ask you to install Duo Mobile for Android. Lie and say you have it installed.

Select "I have Duo Mobile installed".

Duo setup will ask you to activate Duo Mobile for Android. Right-click on the QR code and copy the image location. (Don't select "Email me an activation link instead." This option won't work with duo-hotp.)

Copy the URL of the QR code.

Now, it's time to interact with duo-hotp again.

4. Set up the duo-hotp side

Now, run ./ new 'https://<image URL> to register with Duo. You must be online during this step so duo-hotp can talk to Duo.

duo-hotp should negotiate your shared secret with Duo and store it in secret.json by default. (You can change this with the -s switch.) should output some data at the time of registration, including

HOTP Secret (B32): b'<YOUR-SECRET>'

Make note of this HOTP secret, as you may need it later.

5. Continue

You should now be able to click Continue on the Duo setup.

Click Continue.

You should now be done!

Generating future codes

When you need a new code, just run next (use the -s switch as needed) to generate the next code.

Note: Duo uses HOTP, not TOTP. Codes are not based on time, but on hashes of the secret, with a counter. Don't needlessly iterate this counter by generating codes when you're not logging in.

Using GNOME Authenticator

If you prefer a graphical client, you can use GNOME Authenticator. If you're on Arch, you can get GNOME Authenticator from the AUR. Otherwise, you'll have to use Flatpak (or compile it yourself). (GNOME Authenticator is packaged for Debian, but the package is an old version that does not support HOTP.)

Add Flathub if you haven't already:

flatpak remote-add --if-not-exists flathub

Install GNOME Authenticator:

flatpak install flathub com.belmoussaoui.Authenticator

You can then run it with flatpak run com.belmoussaoui.Authenticator. It might also create an application shortcut. I didn't check.

Inside GNOME Authenticator, you can set up a listing for your account, using the base32 HTOP Secret from step 4. If you lost your base32 secret, here's a tiny script to get it (paste in your base16 secret stored in secrets.json):

#!/usr/bin/env python3
import base64
print(base64.b32encode("<your base16 secret here>".encode("utf-8")))

Open GNOME Authenticator and click the plus (+) symbol in the upper-left corner.

GNOME Authenticator home screen

Enter what you want for Provider and Account. You will need to convince GNOME Authenticator to use custom account settings, rather than one of the built-in providers. I think it opens advanced settings when you enter a provider which is not on the list of suggestions and an HOTP token.

GNOME Authenticator Add a New Account screen without any fields filled out

When the options have expanded, set them as needed. The counter should start at 1 the first time you use that HOTP secret, and it will increment automatically after that. (If you go too far, you can move it backwards here.)

GNOME Authenticator Add a New Account screen with the fields filled out. Counter is set to 1. Algorithm is set to SHA-1. Digits is set to 6.

Click Add when you're done. GNOME Authenticator should now show your current code, and you should be able to forward it with the refresh button.

GNOME Authenticator home screen, now showing the new entry with a code


DISCLAIMER: I am not an Android user (anymore), and I have not tested these methods. I'm listing them because they look useful.

If you use Android but don't want to install the Duo app, you still have options!

There are several free software Android apps which support HOTP. People seem to like Aegis Authenticator. If you don't like Aegis, try searching F-Droid for "HOTP".

Then you'll need to authenticate with Duo and get the shared secret to import into your 2FA app. Some options for this seem to be:


I have a little music player (it's a Sansa Fuze+) running Rockbox, a free replacement firmware for music players.

Ostensibly, Rockbox supports HOTP, but I couldn't get the secrets from duo-hotp working with Rockbox. If I ever figure it out, I'll update this section.