Google Python 中的 OAuth 3 错误

Google OAuth in Python 3 error

我跟随 this awesome answer 在 Python 中实现了 Google OAuth。但是,当我在 Python 3 中尝试 运行 时,我得到了这个错误:

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

此行引发此错误:

o = ord(h[19]) & 15

尝试 o = ord(str(h[19])) & 15 结果:

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

这发生在 Python 3 中,而不是在 Python 2 中,这让我认为某些类型在版本之间发生了变化。这是相关代码:

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

我试图遵循 的回答,但他们没有帮助。第一个答案没有帮助,因为我没有为 keymsg 使用字符串文字。这是我尝试实施第二个答案的建议:

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

此代码在 key_bytes = <...>msg_bytes = <...>:

上引发了此错误
TypeError: encoding without a string argument

使用 utf-8 而不是 latin-1 得到相同的结果。

如果我print(key, msg),我明白了,这表明它们已经是字节形式了:

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

打印的 msg 解释了上面的 ... string of length 3 found 错误。


我不确定从这里到哪里去。任何 suggestions/solutions 都会很棒!

hmac.new() returns 一串字节。在 Python 3 中,这是一个整数数组。因此 h[19] 是一个整数。只需使用该 int 而不是调用 ord()。或者将 h 解码为 str.