【问题标题】:Verifying facebook signed request urls in python3.6在 python3.6 中验证 facebook 签名的请求 url
【发布时间】:2018-04-24 23:47:06
【问题描述】:

我正在尝试使用 python 3.6 验证 facebook signed_requests (https://developers.facebook.com/docs/reference/login/signed-request/) 上的签名。到目前为止,我已经尝试过:

  • facebook python sdk 上的 parse_signed_request() 在这里https://facebook-sdk.readthedocs.io
  • 这种方法facebook signed request email
  • 这也是http://sunilarora.org/parsing-signedrequest-parameter-in-python-bas/
  • 使用 python 2.7 和 3.2
  • 像这样使用 python 密码库

    从 cryptography.hazmat.primitives 导入哈希,hmac 从 cryptography.hazmat.backends 导入 default_backend

    h = hmac.HMAC(key, hashes.SHA256(), backend=default_backend()) h.update(消息) 签名 = h.finalize()

  • 通过简单的replace("-", "+").replace("_", "/")-_ 字符替换为+/ a la Facebook signed_request Invalid。 我对此抱有希望,但我似乎无法验证一个签名,即使它缺少任何上述符号,例如 GlU46mFitdvtOnm56aLR3xQ1RUBzoCY0k2u1kMjBdQA.ey[...] ..so.. 是的..

  • 我在签名/有效负载上尝试了不同的字符串编码(utf-8 / ascii)

  • 不同的哈希算法(sha512 / md5 ..)
  • 首先对 base64 字符串进行哈希处理,然后从 base64 解码它们
  • 重新生成我的应用密码(我已经仔细检查了有效负载中显示的应用 ID 是否引用了正确的应用,因此是密码)

到目前为止,我无法生成与给定签名请求相同的签名......所以每条 facebook 消息都被认为是无效的(不太理想!)。

Facebook 到底是如何生成这些签名的?如何正确生成它们(或不正确,如果它与 facebook 匹配:P 我不挑剔)以验证它们?


编辑:感谢您的评论。我也读过那个链接..它似乎并没有帮助解决这个问题。这是一步一步的例子 -

> import json
> import base64
> from cryptography.fernet import Fernet
> from cryptography.hazmat.backends import default_backend
> from cryptography.hazmat.primitives import hashes, hmac, padding
> from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

# app secret copied straight from developer.facebook.com -> settings -> basic
> secrect = 'obviouslythisisnttherealone'

# signed_request from facebook
> r = 'xik7puSFmT1d1LNBlqFVTOCb8TiH0Rg1xBfr7zzf9rg.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvbW11bml0eV9pZCI6bnVsbCwiaXNzdWVkX2F0IjoxNTI0NTU4NjcxLCJtZXRhZGF0YSI6bnVsbCwicGFnZV9pZCI6MTYxMjU3Njk0NjE4NjAxLCJwc2lkIjoiMTQ2ODkzNzEwNjU2MTA5NSIsInRocmVhZF90eXBlIjoiVVNFUl9UT19QQUdFIiwidGlkIjoiMTQ2ODkzNzEwNjU2MTA5NSJ9'

# spilt on '.'
> b64_sig, b64_data = r.split('.')
> print(b64_sig, b64_data)
xik7puSFmT1d1LNBlqFVTOCb8TiH0Rg1xBfr7zzf9rg eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvbW11bml0eV9pZCI6bnVsbCwiaXNzdWVkX2F0IjoxNTI0NTU4NjcxLCJtZXRhZGF0YSI6bnVsbCwicGFnZV9pZCI6MTYxMjU3Njk0NjE4NjAxLCJwc2lkIjoiMTQ2ODkzNzEwNjU2MTA5NSIsInRocmVhZF90eXBlIjoiVVNFUl9UT19QQUdFIiwidGlkIjoiMTQ2ODkzNzEwNjU2MTA5NSJ9

# there are no - or _ chars to replace in this so ..
> decoded_data = base64.b64decode(b64_data)
> decoded_sig = base64.b64decode(b64_sig + "=")  # add another '=' to pad out the base64 encoding
> print (decoded_data, decoded_sig)
b'{"algorithm":"HMAC-SHA256","community_id":null,"issued_at":1524558671,"metadata":null,"page_id":161257694618601,"psid":"1468937106561095","thread_type":"USER_TO_PAGE","tid":"1468937106561095"}' b'\xc6);\xa6\xe4\x85\x99=]\xd4\xb3A\x96\xa1UL\xe0\x9b\xf18\x87\xd1\x185\xc4\x17\xeb\xef<\xdf\xf6\xb8'

# encode secret into bytes
> bytes_secret = bytes(secret, encoding='ascii')

> h = hmac.HMAC(bytes_secret, hashes.SHA256(), backend=default_backend())
> h.update(decoded_data)
> h.finalize()
b"\xe9\x0f\xbf\xee\xef\xc8\xf0\x96'Im\x1a@\x9d\xc7S\x82%\xe4<\xa0\xbc\xff\x93\xcb\x11~\x7fv\x90\x9f\xb6"
#  ^ wrong

# .. uh .. perhaps in the reverse order?
> h = hmac.HMAC(decoded_data, hashes.SHA256(), backend=default_backend())
> h.update(bytes_secret)
> h.finalize()
b'fnc\xceu\xf8\xf7\xda\xc4\xfe\xca\xe2\x1b\x8b\x00\x9en\xbe\xc7a\xf0P\x9a\\\xfd\xaad\xcb[}E='
# ^ wrong

# ok fine, let's try using a different hashing tool
> import binascii
> hex_sig = binascii.hexlify(decoded_sig)

# the sig we want, in hex
>  print(hex_sig)
b'c6293ba6e485993d5dd4b34196a1554ce09bf13887d11835c417ebef3cdff6b8'

> from hashlib import sha256
> h = sha256(bytes_secret)
> h.update(decoded_data)
> print(h.hexdigest())
'54acbc303f4d85831e4bb9f4818a233e71e7f7c4eef4a585c61ed70f7cf1e07f'
# ^ wrong

# uh ..
> h = sha256(bytes_secret + decoded_data)
> print(h.hexdigest())
'54acbc303f4d85831e4bb9f4818a233e71e7f7c4eef4a585c61ed70f7cf1e07f'
# ^ wrong

# using 2.0.0 facebook python sdk
> import facebook
> facebook.parse_signed_request(r, secret)
False

这些方法都不起作用(这不是我尝试过的所有方法)..

【问题讨论】:

标签: python facebook hmac


【解决方案1】:

更新:希望这对寻找类似东西的其他人有所帮助 - 签名生成功能是正确的,在某些前端代码中隐藏的(错误)应用程序 ID 硬编码存在错误。

【讨论】:

    猜你喜欢
    • 2012-05-01
    • 2018-08-25
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-11
    • 2010-10-10
    • 2022-07-20
    相关资源
    最近更新 更多