clj-totp
TOTP (Time-based One Time Password) in clojure. It supports several digest algorithms and length.
What is TOPT
The TOPT is a standard used to generate a time-based password. Usually, this password is used as a second factor authentication.
You can read more about the algorithm here:
- Wikipedia: https://en.wikipedia.org/wiki/Time-based_one-time_password
- TOTP RFC: https://web.archive.org/web/20110711124823/http://tools.ietf.org/html/rfc6238
- HOTP RFC: https://www.ietf.org/rfc/rfc4226.txt
How to use
First, you must have installed a Java Runtime Environment. Check https://adoptium.net/es if you are unsure how to install.
The project is distributed as a jar file with all dependencies included (a.k.a. "uberjar"), and uses a simple script to launch the program. Script and uberjar must be in the same directory.
Execute without parameters to show main commands
clj-totp.sh
A quick description of each command:
generate: Show a TOTP with a given secret and parameters, not stored in config.config: Manage configuration fileadd: Store a new TOTP configurationdelete: Delete an stored configurationlist: Shows a list of TOPT stored configurationsget: Generate a TOTP previously addedimport: Import a URL with the TOTP configuration
Quick and simple generation
If you want to quickly generate a TOPT, you only need to suministrate the secret in B32 format:
clj-totp.sh generate <B32 secret>
The OTP changes every 30 seconds, you can print every change with -c option:
clj-totp.sh generate -c <B32 secret>
It will update the TOTP every 30 seconds, until you press <Enter> or <ctrl+c>.
Store your configurations
Writing the B32 secret each time can be a bit tedious, but you can store secrets for your applications. Be carefull, this version don't encrypt passwords, secrets are saved in plain text in a file in your home dir.
With the config command you can check your configuration file. Now, let's explorer the subcommands:
Check if the config file exists, and show the full path:
clj-totp.sh info config
Create a new config file, if the file exists, it will prompt you if you want to overwrite it:
clj-totp.sh info init
Show all data contained in the config file, as a table:
clj-totp.sh info show
Use stored configurations
If you have a valid configuration file, it's time to configure some applications.
To add a new configured application, you can use the add command. The simplest way to add a new
configuration is to specify an alias and the secret in B32:
clj-totp.sh add <alias> <b32 secret>
The add subcommand has a lot of configuration options, you can explore them wit the -? param.
To list all added configurations, use the list command:
clj-totp.sh list
If you made a mistake, you can delete a configured app with the delete command:
clj-totp.sh delete <alias>
When you have some configured apps, it's time to use them, with the get command. To generate a
single TOTP for some app you can simple pass a list of alias:
clj-totp.sh get <alias1> <alias2> <aliasN>
It will show the TOTP value at the current time, but TOTPs changes every 30 seconds, to show
the value when it changes, add the -c param. It will update the TOTP for each alias until you
press enter key (or ):
clj-totp.sh get <alias1> <alias2> <aliasN> -c
Finally, this program has an import command, that can import from a decoded QR or exported data
from Google Autenticator:
clj-totp.sh import <alias> "<url>"
Project's plan
v1.0
- Functional TOTP generation
- Get TOTP from command line
- Continuous generation
v1.1
- Store configuration in a properties file or simple DB
- Import from
otpauthandotpauth-migrationprotocols - Show several OTPs at once
v1.2
- Show progress bar
- Styles for progress bar
- Native compilation script corrections
v2
- REST API
- User management
- Robust BD backend (H2, datomic, or similar)
v3
- Simple web connected to REST API
Ideas
Some ideas for future versions:
- Store passwords securely: https://github.com/weavejester/crypto-password
Building the project
This project is done 100% in clojure. It uses deps.edn for configuring the project and build.clj
for defining compilation tasks.
The first step is to install Java JDK, version 11 or newer (version 21 recommended).
To execute manually the main function, simple use the :run alias:
clojure -M:run <commands and parameters>
To build the uberjar:
clojure -T:build uber
There is a utility script to build a native executable using Graal VM. Please, edit the script and check the path to your Graal installation. Use it at your own risk.
native.sh
