I have owned way too many cellphones. I’d like to break free of Android without switching to iOS, but one of the applications I’m required to have for work is Okta Verify. Moving from Okta Verify to an open source solution was easier than I expected, but the path to discovering how to do so was not a simple one. The following explains how to get the secret used for Okta’s multi-factor auth codes, and use it in open source alternatives to Okta Verify, as well as in Python scripts.
The first time someone signs into an organization’s Okta portal with Multi-Factory Authentication enabled, they’ll be asked to setup a Multi-Factor Device. A QR code is presented to the user with an
otppath URL. Time based One Time Passwords (TOTP) are an official standard defined in RFC 62381. Unfortunately, the URL parameters Okta Verify uses are not standard.
otpauth://totp/example.okta.com:username%40example.com? issuer=example.okta.com&t=*******&f=*****&s=https%3A%2F%2Fexample.okta.com& touchIdRequired=false
otppath QR codes, including those used by Google Authenticator, contain a parameter called
secret that contains the shared key that’s use to generate TOTPs. The above
otppath does not have this parameter. A developer might think they could simple look up the specification for the
otpauth protocol, except there isn’t one. References to it first appeared in Google Authenticator in 2010, but the commit message suggested it came from a BlackBerry source before it2.
Digging through the Okta documentation, it appears that
t represents the activation token and
f, represents the factor id. I started digging through the Okta API to see if there was a way to use this information to retrieve the secret. I also started digging through the app’s data directory on my rooted phone to see if I could find and decrypt the secret.
However, such searching was unnecessary. I had glossed over a prior article on Okta’s official blog where Micah Silverman described making a hardware TOTP generator using a Audrino3. Since the device lacked a real time clock, the device had to be set to the current time whenever it was turned on. The guide shows that it was possible to get the secret needed for a TOTP generator simply by clicking on the
Can't Scan link under the QR code.
This secret can be used with any RFC 6238 compatible TOTP generator. The following is a Python script that uses pyotp to generate a TOTP and copy it to the clipboard using pyperclip.
#!/usr/bin/env python3 import pyotp import pyperclip totp = pyotp.TOTP("<insert your secret here>") pyperclip.copy(totp.now())
You can also use this code with mobile open source authenticators including FreeOTP and andOTP, both of which are available on F-Droid.
Having open standards can help prevent vendor lock-in. Although it took a little work and isn’t as transparent as I’d like, I’m glad Okta provides an easy way for end users to grab their TOTP secret through their web UI so it can be used in any 3rd party verification application.