在python3.6中验证facebook签名的请求网址

时间:2018-04-23 16:06:14

标签: python facebook hmac

我尝试使用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 import default_backend

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

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

    < / LI>
  • 我在签名/有效负载上尝试了不同的字符串编码(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

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

1 个答案:

答案 0 :(得分:0)

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