1

I followed this awesome answer for implementing Google OAuth in Python. However, when I tried running in Python 3, I get this error:

TypeError: ord() expected string of length 1, but int found

This error is thrown by this line:

o = ord(h[19]) & 15

Trying o = ord(str(h[19])) & 15 resulted in:

TypeError: ord() expected a character, but string of length 3 found

This happens in Python 3, but not in Python 2, which makes me think that some types have changed between versions. This is the relevant code:

def get_hotp_token(secret, intervals_no):
    key = base64.b32decode(secret)
    msg = struct.pack(">Q", intervals_no)
    h = hmac.new(key, msg, hashlib.sha1).digest()
    o = ord(h[19]) & 15
    h = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
    return h

I tried to follow this question's answers, but they did not help. The first answer did not help because I am not using a string literal for key or msg. This was my attempt at implementing the second answer's suggestion:

def get_hotp_token(secret, intervals_no):
    key = base64.b32decode(secret)
    key_bytes = bytes(key, 'latin-1')

    msg = struct.pack(">Q", intervals_no)
    msg_bytes = bytes(msg, 'latin-1')

    h = hmac.new(key_bytes, msg_bytes, hashlib.sha1).digest()
    o = ord(h[19]) & 15
    h = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
    return h

This code threw this error on the key_bytes = <...> and msg_bytes = <...>:

TypeError: encoding without a string argument

Using utf-8 instead of latin-1 had the same result.

If I print(key, msg), I get this, which suggests that they are already in a byte-like form:

b'fooooooo37' b'\x00\x00\x00\x00\x02\xfa\x93\x1e'

The msg printed explains the ... string of length 3 found error above.


I am unsure where to go from here. Any suggestions/solutions would be great!

Daniel
  • 3,188
  • 14
  • 34

1 Answers1

1

hmac.new() returns a string of bytes. In Python 3 this is an array of integers. Hence h[19] is an integer. Just use that int instead of calling ord(). Or decode h to str.

phd
  • 82,685
  • 13
  • 120
  • 165