A Rust CLI to more safely generate a QR code from a 32-character TOTP secret key. Can also read QR codes from image files and present the TOTP secret key.
The problem this tool tries to solve
QR code --> TOTP secret key: You're enabling two-factor authentication on an online account. A service provides you with QR code for you to take a photo of with your phone's authentication app (like Google Authenticator). That's all fine and good, but what if you want to save this QR code (or really, the secret key it contains) somewhere else, or share it with someone you trust?
QRForge accepts an image file of the QR code and displays or "reads" the discovered 32-character string that is the TOTP secret key, which you can write down on paper or paste into a password manager. To do this, you'd run
qrforge read <qr_code_image_file_path.png>
TOTP secret key --> QR code: You've got a 32-character TOTP secret and, for convenience, you want to generate, or "draw", a QR code so you can get it into your phone's authentication app. You can do this with QRForge by running
qrforge draw. You'll then be prompted to enter the secret and other information about the account.
After you get through some prompts, a QR code will be displayed in your terminal. You'll also be given the choice to save the QR code to an image file.
But is it actually secure?
Honestly, I'm not sure. But since QRForge uses rpassword to take in the secret key, I figure it's better than using a generic tool for creating QR codes, like qrencode, which may store your secret key in your shell's history and potentially elsewhere.
Know that KeePassXC version 2.4.0 and above can generate TOTP QR codes (see FAQ and relevant pull request) and more. If you can, I'd recommend using KeePassXC rather than this tool for managing your TOTP keys and QR codes.
- Install Rust if you haven't already
cargo install --git https://github.com/sts10/qr-forge --branch main
Alternatively: Clone repo,
cd into repo directory, and run
cargo install --path=.
USAGE: qrforge <SUBCOMMAND> FLAGS: -h, --help Prints help information -V, --version Prints version information SUBCOMMANDS: draw Draw a QR code from text secret, service, and username help Prints this message or the help of the given subcommand(s) read Read a QR code image file to an OTPauth URI
draw subcommand has its own options, including
USAGE: qrforge draw [OPTIONS] FLAGS: -h, --help Prints help information -V, --version Prints version information OPTIONS: -o, --output <output> Print created QR code to a file
qrforge read path/to/qr_code.pngreads a TOTP secret from an image of a QR code.
qrforge drawprompts the user to draw or create a QR code from a TOTP secret and other information.
qrforge draw -o /path/to/new-created-qr-code.pngprompts user to create QR code and saves the resulting QR code to specified file.
This program's setting reading and creating TOTPs is hard-coded to some sensible default (30 seconds, one type of secret key, etc.). I also need to test it on image file types other than PNG.
If generated codes aren't accepted by the online service, check to make sure your computer's time is accurate.
Notes / reference
Here are the official specifications of the otpauth URI format from Google, if helpful.
Before I wrote this code, I wrote a blog post that might help you understand the problems I'm interested in here.
- Add ability to generate a few 6-digit codes, allowing users to confirm everything went right. See this function for clues on how to do this.
- Make this a real CLI using structopt or Clap
- Big refactor of the reading image code
- Provide ability to handle non-standard TOTP codes