用PHP

时间:2018-01-09 22:04:02

标签: php surveymonkey

我已在PHP应用程序中成功实施了一个webhook,但我不确定如何验证Sm-Signature标题。

文档here声明:

  

我们的webhook回调作为POST请求发送并包含   以下可用于验证请求的请求标头   来自SurveyMonkey:

Sm-Apikey: Your Client ID or API key (if you’re using OLD Authentication)
Sm-Signature: # HMAC digest hashed with sha1

我能找到的解释如何完成的唯一documentation是用Python编写的,我根本不熟悉。提供的Python代码是:

import hashlib
import hmac
import base64

def generate_signature(payload, api_key, api_secret):

"""
:type payload: str The response body from the webhook exactly as you received it
:type api_key: str Your API Key for you app (if you have one) otherwise your Client ID
:type api_secret: str Your API Secret for your app
:return: str
"""

# ensure all strings passed in are ascii strings,
# as hmac does not work on unicode

api_key = api_key.encode("ascii")
api_secret = api_secret.encode("ascii")
payload = payload.encode("ascii")

signature = hmac.new(
key='%s&%s' % (api_key, api_secret),
msg=payload,
digestmod=hashlib.sha1)

signature_digest = signature.digest()

return base64.b64encode(signature_digest)

# Compare the signature generated from the request body against the one in the request headers
# Where "request" is the HTTP request received for the event, attributes to access body/headers may vary by framework
hmac.compare_digest(generate_signature(request.body, api_key, api_secret), request.headers['Sm-Signature'])

除了不精通Python之外,我还不熟悉PHP的散列,摘要和其他加密功能。我如何将其解释为PHP和/或解释如何在PHP中执行此验证?

编辑:我很感激努力指出我正确的方向,但我已尝试过该代码,以及其他几个答案的代码,但没有一个产生我需要的结果。此外,我在SurveyMonkey的特定上下文中询问。我没有找到有关SurveyMonkey的v3 webhook验证的PHP实现的文档。这不是重复,因为我的问题具体是如何执行此验证。

到目前为止,我已经尝试了所有这些变体,其中$raw是未解析的POST邮件正文,$api_sigSm-Signature标题值,$api_key是关键作为Sm-Apikey标题传递,API_CLIENT_ID是我的客户ID(实际上与Sm-Apikey相同)。

// Various combinations, each with and without base64 encoding.
hash_hmac('sha1', $raw, $api_key)
base64_encode(hash_hmac('sha1', $raw, $api_key))
hash_hmac('sha1', $raw, $api_sig)
base64_encode(hash_hmac('sha1', $raw, $api_sig))
hash_hmac('sha1', $raw, API_CLIENT_ID)
base64_encode(hash_hmac('sha1', $raw, API_CLIENT_ID))
hash_hmac('sha1', $raw, "$api_key&$api_sig")
base64_encode(hash_hmac('sha1', $raw, "$api_key&$api_sig"))
hash_hmac('sha1', $raw, API_CLIENT_ID."&$api_sig")
base64_encode(hash_hmac('sha1', $raw, API_CLIENT_ID."&$api_sig"))

// This time with raw outputs.
hash_hmac('sha1', $raw, $api_key, TRUE)
base64_encode(hash_hmac('sha1', $raw, $api_key, TRUE))
hash_hmac('sha1', $raw, $api_sig, TRUE)
base64_encode(hash_hmac('sha1', $raw, $api_sig, TRUE))
hash_hmac('sha1', $raw, API_CLIENT_ID, TRUE)
base64_encode(hash_hmac('sha1', $raw, API_CLIENT_ID, TRUE))
hash_hmac('sha1', $raw, "$api_key&$api_sig", TRUE)
base64_encode(hash_hmac('sha1', $raw, "$api_key&$api_sig", TRUE))
hash_hmac('sha1', $raw, API_CLIENT_ID."&$api_sig", TRUE)
base64_encode(hash_hmac('sha1', $raw, API_CLIENT_ID."&$api_sig", TRUE))

这些都没有产生匹配Sm-Signature的值,并且所有输出都是Sm-Signature长度的2-3倍。我怀疑需要另一种编码(在HMAC摘要之前和/或之后),但我不知道它会是什么。

编辑2 :感谢Kandalaft将军的示例代码,我找到了解决方案。我没有把握哪些数据作为关键,但他的建议有所帮助。这与我在研究此问题时遇到的信息相结合,使我能够成功执行验证。对于那些寻找这个答案的人来说,它是:

base64_encode(hex2bin(hash_hmac('sha1', $raw, API_CLIENT_ID.'&'.API_SECRET)));

如果管理员可以删除重复的标签,以便我可以将解决方案作为正确答案发布,我将不胜感激。

0 个答案:

没有答案