If you enabled 2-step authentication on your Google account (which you should definitely do, BTW), you know the way it works is you have an app on your phone called Google Authenticator that displays six-digit codes that change every 30 seconds. When you log in, you enter the currently displayed code in addition to your password. That way when bad people get a hold of your password, they still cannot use your account, because they don't have the code. (BTW, this isn't specific to Google accounts, the authentication scheme is described in RFC 6238 and is used by other services like Dropbox and LastPass. You can even set it up so that your own servers ask you for a code when you ssh into them.)
Where do the codes come from? When you set up 2-step authentication, the service (for example Google) gives you a secret that is then stored in the app (it's usually done through a QR code so that you don't have to type in long sequences of numbers). The app generates codes by taking the secret together with current time and performing some cryptographic operations on them (mostly the SHA-1 hash function). There's no reason we can't do the same on our TIMESQUARE watch and indeed someone has already implemented the algorithm on Arduino. I took that implementation and put it as another display mode on the watch, showing the six-digit code using the marquee effect normally used to display time.
If you want to try it on your watch, you can download the code here. You will need to install Adafruit's original code for the watch and their GFX library in your Arduino IDE. You're also going to need a way to program the watch from your computer. I used Adafruit's FTDI Friend. They have a tutorial on how to do this.
The authentication secret is currently hardcoded in the TOTP.ino file. I should probably make it so that it's possible to set the secret using the buttons on the watch, but right now you're going to have to set it manually in the hmacKey1 variable. Google gives you the secret in Base32-encoded form, but you can easily convert it to an array of bytes using the following Python code (remove the spaces from the Base32 string Google gives you):
import base64 print ', '.join([hex(ord(i)) for i in base64.b32decode('JBSWY3DPEHPK3PXP')])Be aware that compiling code using the Arduino IDE can leave some intermediate files in the /tmp directory (or its equivalent on other operating systems). You should clean them up to remove traces of the secret from your computer.
Fantastic! This is a great example of how to make use of the watch...
ReplyDeleteFinally got my watch, plugged in the code and my keys, ran the python script, copied the bytes.. and am getting a way different number than what was on my phone. :)
ReplyDeleteThis one is going to be hard to debug! Any tips?
jake@whoisjake.com
Did you set the correct time? :)
DeleteI did, that's why it's perplexing to me :) I might try again to regenerate with new secrets on both the app and the watch to see.
ReplyDeleteHow do you get that Base32 key from google? I've looked all over their site and was unable to get a key in the format you are showing... just something in groups of 4 characters that is much much longer.
ReplyDelete