Skip to content

Instantly share code, notes, and snippets.

@href
Created August 30, 2016 11:27
Show Gist options
  • Save href/dad244512c320bd9b5d6ff50e7c7e0b2 to your computer and use it in GitHub Desktop.
Save href/dad244512c320bd9b5d6ff50e7c7e0b2 to your computer and use it in GitHub Desktop.
Calculate the Yubikey serial number from the OTP
# adapted from Java:
# https://github.com/Yubico/yubikey-salesforce-client/blob/
# e38e46ee90296a852374a8b744555e99d16b6ca7/src/classes/Modhex.cls
ALPHABET = 'cbdefghijklnrtuv'
def yubikey_otp_to_serial(otp):
""" Takes a Yubikey OTP and calculates the serial number of the key.
The serial key is printed on the yubikey, in decimal and as a QR code.
Example:
>>> yubikey_otp_to_serial(
'ccccccdefghdefghdefghdefghdefghdefghdefghklv')
2311522
"""
token = 'cccc' + otp[:12]
toggle = False
keep = 0
bytesarray = []
for char in token:
n = ALPHABET.index(char)
toggle = not toggle
if toggle:
keep = n
else:
bytesarray.append((keep << 4) | n)
value = 0
# in Java, shifts on integers are masked with 0x1f using AND
# https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.19
mask_value = 0x1f
for i in range(0, 8):
shift = (4 - 1 - i) * 8
value += (bytesarray[i] & 255) << (shift & mask_value)
return value
if __name__ == '__main__':
assert yubikey_otp_to_serial(
'ccccccdefghdefghdefghdefghdefghdefghdefghklv') == 2311522
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment