Using OATH Toolkit with Dropbox

Today there was an announcement that Dropbox supports two-factor authentication. On their page with detailed instructions there is (at the bottom) a link to the man page of the OATH Toolkit command line utility oathtool. OATH Toolkit is available in Ubuntu 12.04 and Debian Wheezy. (Note that the 1.10.4 version in Ubuntu does not support the base32 features.) There is not a lot of details in the documentation on Dropbox’s site on how to use oathtool, but I have experimented a bit with the setup and I’d like to share my findings. I assume you are somewhat familiar with the OATH Toolkit; if not I suggest reading my earlier introduction to OATH Toolkit.

To use OATH Toolkit’s command line utility to generate OTPs that are accepted by Dropbox, here is how you proceed. When you enable two-factor authentication on Dropbox’s site, you must select “Use a mobile app” and on the next screen with the QR code image, click the “enter your secret key manually” link. You will then be presented with a code that looks like this: gr6d 5br7 25s6 vnck v4vl hlao re

Now this code is actually space-delimitted base32 encoded data, without any padding. Since version 1.12.0, oathtool can read base32 encoded keys. However, parsing the raw string fails, so to make it work, you need to remove the spaces and add padding characters. I have yet to see any documentation on the Dropbox implementation, but I assume they always generate 16 binary octets that are base32 encoded into 26 characters like the codes that I have seen. The code is the cryptographic key used for the HMAC-SHA1 computation described in the RFC 6238 that specify OATH TOTP. If you study the base32 encoding you discover that 26 characters needs six pad characters. So converted into proper base32, the string would be gr6d5br725s6vnckv4vlhlaore======. Now generating OTPs are easy, see below.

jas@latte:~$ oathtool --verbose --totp --base32 "gr6d5br725s6vnckv4vlhlaore======"
Hex secret: 347c3e863fd765eab44aaf2ab3ac0e89
Base32 secret: GR6D5BR725S6VNCKV4VLHLAORE======
Digits: 6
Window size: 0
Step size (seconds): 30
Start time: 1970-01-01 00:00:00 UTC (0)
Current time: 2012-08-27 21:22:54 UTC (1346102574)
Counter: 0x2ACA9C5 (44870085)

125860
jas@latte:~$

Dropbox’s implementation is robust in that it requests a valid OTP from me, generated using the secret they just displayed, before proceeding. This verifies that the user was able to import the key correctly, and that the users’ OATH TOTP implementation appears to work. If I type in the OTP generated from oathtool this way, it allowed me to enable two-factor authentication and I agreed. From that point, signing into the Dropbox service will require a OTP. I invoke the tool, using the same arguments as above, and the tool will use the current time to compute a fresh OTP.

Reflecting on how things could work smoother, I suppose oathtool could be more permissive when it performs the base32 decoding so that the user doesn’t have to fix the base32 spacing/padding manually. I’ll consider this for future releases.

12 Replies to “Using OATH Toolkit with Dropbox”

  1. I have been looking into this, but the emergency code I was given was 16 characters and cannot figure out the correct padding. i even went nuts and incrementally added from 1 to 38 =’s to the end of my 16 digit code. no dice. I’ll stay tuned for updates. i even tried a method i found on another site, which didn’t get past the “if” statement as 16 % 4 is 0

    if len(str) % 4 != 0 {
    str += strings.Repeat(“=”, 4 – len(str) % 4)
    }

    source: http://comments.gmane.org/gmane.comp.lang.go.general/56519

  2. I see where I made the mistake, I used the wrong code. It’s working now that i read the blog for the third time. Thanks!

  3. matt: Yes that it right, the emergency code is just a long-term static password, I don’t think there is any semantics in it. So just store a copy of that in case you’ll ever need it. Since the “normal” code and the emergency code look similar, I can see how a mistake like this happens… maybe something for the Dropbox team to consider.

  4. Any idea how to get the “normal” code out of Dropbox later. I used the QR-code method to enter it directly into my smartphone app, before I knew about OATH. Now I’d like to be able to use OATH as well.

  5. dB: First, just a minor correction, OATH is the technology used here, and you are using it already with your app — “OATH Toolkit” is my implementation of the OATH protocols. I’m assuming you mean you want to test it with OATH Toolkit… I haven’t found any way to get this information out of dropbox, so you need to get it from your smartphone app — there is usually a way to display the secret, do you see any? I suppose it would display the secret in the space-separated format used by dropbox too, since it originally comes from Google (I think).

    /Simon

  6. I had trouble getting this to work using the homebrew version of oathtool. The issue ended up being I had to upper case the key.

    echo “YOUR KEY” | tr ‘a-z’ ‘A-Z’

    This solved my issue. Thanks for the post!

  7. Thanks for the terminology clarification.

    Yes, I did think to ask my smartphone app, but couldn’t see any option of extracting it. I guess it tries to keep it pretty secret.

    For now I’m doing fine with the smartphone app, and have the emergency static password if I ever need it. I guess if I get really keen to be able to use OATH Toolkit, I can switch 2-stage off at Dropbox, and then turn it back on again, and this time make sure I capture the key manually rather than via QR.

  8. bubba: The lower/upper-case base32 issues was fixed in version 1.12.1. Are you using 1.12.0 perhaps?

  9. dB: Yes, it is easy to switch 2-stage off and then turn it back on again. I’ve done it a few times when experimenting. Btw, which smartphone app are you using?

  10. Firstly, thanks for putting together this tool and for going to the bother to work out what dropbox is up to (:

    I’m trying to setup oath with dropbox and oathtool tells me “tbase32 decoding failed: Base32 string is invalid” with the secret keys dropbox is giving me.

    Here’s a couple of examples, munged (I hope!) in the way you describe:
    ey2rguxrwcrby2zkxmzhlehvpi======
    7yvmstupib7mqoiceufgrpyhja======
    EY2RGUXRWCRBY2ZKXMZHLEHVPI======
    (the third is the first in uppercase – just in case it made a difference). They’re all the same length as your example.

    When I put in the key you used as an example however, it works! I’m guessing dropbox has changed something??

    I’m using oathtool from ubuntu qantal: oathtool (OATH Toolkit) 1.12.4