Unicode-objects 必须在散列前编码 Python 3.6 Vuforia

Unicode-objects must be encoded before hashing Python 3.6 Vuforia

我试图从 vuforia 的 API 获取我的目标,但我无法传递 header "Authorization" 的最后一个值,这是一个编码数据,错误我得到的是:

Unicode-objects 必须在散列前编码

这是代码的尝试片段,我遵循 vuforia's documentation 但是,我的代码仍然有问题,我不知道它是什么

import base64
import hashlib
import hmac

import requests
from flask import Flask, request
from email.utils import formatdate
import logging

app = Flask(__name__)


@app.route('/')
def hello_world():
    try:
        import http.client as http_client
    except ImportError:
        # Python 2
        import httplib as http_client
    http_client.HTTPConnection.debuglevel = 1

    logging.basicConfig()
    logging.getLogger().setLevel(logging.DEBUG)
    requests_log = logging.getLogger("requests.packages.urllib3")
    requests_log.setLevel(logging.DEBUG)
    requests_log.propagate = True

    url = 'https://vws.vuforia.com/targets'
    req = requests.Request('GET', url)
    req.headers = setHeaders(req)
    resp = requests.Session().send(req.prepare())

    return resp.text


def compute_md5_hex(data):
    """Return the hex MD5 of the data"""
    h = hashlib.md5()
    h.update(data)
    return h.hexdigest()


def compute_hmac_base64(key, data):
    """Return the Base64 encoded HMAC-SHA1 using the provide key"""
    h = hmac.new(key, None, hashlib.sha1)
    h.update(data)
    return base64.b64encode(h.digest())


def setHeaders(request):
    date = formatdate(None, localtime=False, usegmt=True)
    accessKey = "ce1500fhfth429279173fd839f9d414532014a3da"
    secret_key = b"5d3fdawd7211447c35be607ae5a08ec794a09d71d"
    headers = {'Date': date, 'Authorization': "VWS " + accessKey + ":" + tmsSignature(request, secret_key)}

    return headers


def tmsSignature(request, secretKey):
    method = request.method
    contentType = ""
    hexDigest = "d41d8cd98f00b204e9800998ecf8427e"
    if method == "GET" or method == "POST":
        pass
        # Do nothing because the strings are already set correctly
    elif method == "POST" or method == "PUT":
        contentType = "application/json"
        # If this is a POST or PUT the request should have a request body
        hexDigest = compute_md5_hex(request)
    else:
        print("ERROR: Invalid content type passed to Sig Builder")

    # Date in the header and date used to calculate the hash must be the same
    dateValue = formatdate(None, localtime=False, usegmt=True)
    requestPath = str(request.url)
    components_to_sign = list()
    components_to_sign.append(method)
    components_to_sign.append(str(hexDigest))
    components_to_sign.append(str(contentType))
    components_to_sign.append(str(dateValue))
    components_to_sign.append(str(requestPath))
    string_to_sign = "\n".join(components_to_sign)
    shaHashed = ""
    try:
        shaHashed = compute_hmac_base64(secretKey, string_to_sign)
    except Exception as e:
        print("ERROR ", e)
    return shaHashed


if __name__ == '__main__':
    app.run()

查看您的 hmac_base64_key 函数,这个特定的调用是原因:

h.update(data)

因为这是 hmac 库中的 update 函数,它要求输入是字节而不是 string/unicode(查看 hmac which refers to hashlib 上的文档它的 update 签名)。

看来解决方法很简单:

h.update(data.encode("utf8"))  # or other encoding you want to use

请注意,您需要将 compute_hmac_base64 (shaHashed) 的 return 值再次更改为字符串,因为您要将它与 [=18= 中的字符串连接起来].

(我假设一个 Python 3 代码,即使你顺便检查了代码中的 Python 2,因为你已经标记了这个 Python 3 ).