Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions pingpp/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import sys
import os



logger = logging.getLogger('pingpp')

__all__ = ['StringIO', 'parse_qsl', 'json', 'utf8']
Expand Down Expand Up @@ -53,3 +55,37 @@ def utf8(value):
def is_appengine_dev():
return ('APPENGINE_RUNTIME' in os.environ and
'Dev' in os.environ.get('SERVER_SOFTWARE', ''))


def webhooks_verify(path_pubkey, private_sign, req_data):
""" path_pubkey : 公钥文件路径,内容为ping++提供的公钥(账户和设置 - Ping++ 公钥)
private_sign: ping++对应的私钥签名后的字符串
req_data : 请求的json格式字符串,不要get_json(),因为会改变字段的顺序,直接获取原始字符串即可
备注:遇到一个坑,直接从官网上copy公钥时,vim保存文件时会多一个字符,导致验算不通过,推荐notepad++保存
最后一行不要有换行符
"""
import base64

from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256

def decode_base64(data):
missing_padding = 4 - len(data) % 4
if missing_padding:
data += b'='*missing_padding
return base64.decodestring(data)

sig = decode_base64(private_sign)
req_data = req_data.encode('utf-8')
digest = SHA256.new(req_data)
pubkey = RSA.importKey(open(path_pubkey).read())
pkcs = PKCS1_v1_5.new(pubkey)

return pkcs.verify(digest, sig)


def webhooks_verify_for_flask(path_pubkey, request):
private_sign = request.headers['x-pingplusplus-signature']
req_data = request.data
return webhooks_verify(path_pubkey, private_sign, req_data)