OTP API

yubiotp.otp

Implementation of the Yubico OTP algorithm. This can generate and parse OTP structures.

>>> from binascii import unhexlify
>>> key = b'0123456789abcdef'
>>> otp = OTP(unhexlify(b'0123456789ab'), 5, 0x0153f8, 0, 0x1234)
>>> _ = repr(otp)  # coverage
>>> _ = str(otp)  # coverage
>>> token = encode_otp(otp, key, b'cclngiuv')
>>> token == b'cclngiuvttkhthcilurtkerbjnnkljfkjccklkhl'
True
>>> public_id, otp2 = decode_otp(token, key)
>>> public_id == b'cclngiuv'
True
>>> otp2 == otp
True
exception yubiotp.otp.CRCError[source]

Raised when a decrypted token has an invalid checksum.

class yubiotp.otp.OTP(uid, session, timestamp, counter, rand)[source]

A single YubiKey OTP. This is typically instantiated by parsing an encoded OTP.

Parameters:
  • uid (bytes) – The private ID as a 6-byte binary string.

  • session (int) – The non-volatile usage counter.

  • timestamp (int) – An integer in [0..2^24].

  • counter (int) – The volatile usage counter.

  • rand (int) – An arbitrary number in [0..2^16].

pack()[source]

Returns the OTP packed into a binary string, ready to be encrypted and encoded.

classmethod unpack(buf)[source]

Parse a packed OTP. This is the complement to pack() so the buffer should be a decoded, decrypted OTP buffer.

Parameters:

buf (bytes) – A packed OTP structure.

Raises:

CRCError if the buffer does not pass crc validation.

class yubiotp.otp.YubiKey(uid, session, counter=0)[source]

A simulated YubiKey device. This can be used to generate a sequence of Yubico OTP tokens.

Parameters:
  • uid (bytes) – The private ID as a 6-byte binary string.

  • session (int) – The non-volatile usage counter. It is the caller’s responsibility to persist this. Note that this may increment if the volatile counter wraps, so you should only increment and persist this after you have finished generating tokens.

  • counter (int) – The volatile session counter. This defaults to 0 at init time, but the caller can override this.

generate()[source]

Return a new OTP object, as if the user had pressed the YubiKey button.

Return type:

OTP

yubiotp.otp.decode_otp(token, key)[source]

Decodes a modhex-encoded Yubico OTP token and returns the public ID and the unpacked OTP object.

Parameters:
  • token (bytes) – A modhex-encoded buffer, as generated by a YubiKey device. Decoded, this should consist of 0-16 bytes of public ID followed by 16 bytes of encrypted OTP data.

  • key (bytes) – A 16-byte AES key as a binary string.

Returns:

The public ID in its modhex-encoded form and the OTP structure.

Return type:

(bytes, OTP)

Raises:

ValueError if the string can not be decoded.

Raises:

CRCError if the checksum on the decrypted data is incorrect.

yubiotp.otp.encode_otp(otp, key, public_id=b'')[source]

Encodes an OTP structure, encrypts it with the given key and returns the modhex-encoded token.

Parameters:
  • otp (OTP) – The OTP structure.

  • key (bytes) – A 16-byte AES key as a binary string.

  • public_id (bytes) – An optional public id, modhex-encoded. This can be at most 32 bytes.

Raises:

ValueError if any parameters are out of range.