Over a million developers have joined DZone.

Implementing One-Time Passwords in Crystal

DZone 's Guide to

Implementing One-Time Passwords in Crystal

Want to learn more about how to implement one-time passwords on your app with Crystal? Check out this tutorial to learn more about creating one-time passwords.

· Security Zone ·
Free Resource

The Crystal language logo

Crystal is still a young language; there aren’t a lot of libraries available yet. For some, this could be offputting, but for others, this is a chance to learn about a language and provide useful tools for those also starting to use it.

I’ve given a number of talks over time, some of which were about two-factor authentication. A while back, I took the opportunity to improve my knowledge and implement the one-time password algorithm in Crystal.

This led me to build the CrOTP library for one-time passwords in Crystal.

If you want to check out the code, most of the important implementation can be found in the CrOTP::OTP module. The CrOTP::HOTP and CrOTP::TOTP classes take care of the different ways the counter is treated.

Using CrOTP

To use the CrOTP library in your own Crystal project, you need to add it to the dependencies in your shard.yml file.

    github: philnash/crotp

Then, install the dependencies with shards install.

Now, you can require "crotp" and use it in your application. Most users on the web of one-time passwords are time-based tokens for two-factor authentication. Here’s how to generate and verify time-based OTPs.

Getting Started

First, require the library and generate a random string to use as the secret.

require "crotp"

secret = Random.new.hex(16)

Then, create an instance of the CrOTP::TOTP class with that secret.

totp = CrOTP::TOTP.new(secret)

Sharing Secrets

You can generate a URI that can be shared with authenticator apps, like Authy or Google Authenticator. To do so, call authenticator_uri with the name of your app as the issuer and the user account’s username as the user.

totp.authenticator_uri(issuer: "Test app", user: "philnash@example.com")

Turn the resulting URI into a QR code, and users can scan it to add the account to their app.

Generating and Verifying

Now, you can use the totp object to generate a new one-time password that will be valid within the current 30 second period of time.

password = totp.generate

To verify a code, you can use the same object, calling verify instead.


You can also allow a drift to give users more time to enter their code. The drift is the number of periods (periods are 30 seconds long by default) that can pass after the token was generated.

totp.verify(password, at: Time.now, allowed_drift: 2)

There are more examples in the project repo.

There's More Work to Be Done

CrOTP does the basic work for generating and verifying one-time passwords. Of course, there’s more to do on the project when I find the time.

I’d love to hear if this project is useful to you or if you’re interested in helping implement the missing features. Let me know on Twitter at @philnash.

security ,crystal ,password ,authentication ,one-time password ,two-factor authentication

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}