# encoding:utf-8 # env:python 2.7 # author:SunXiuWen # datetime:2019/11/20 0020 9:04 import base64 import urllib import traceback from Crypto.Hash import SHA256 from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 """生成签名与验签demo 注:rsa算法使用PKCS1而不是PKCS8 """ def check_string(params): """ 整理请求方式,路径及请求参数字符串 :param params:请求报文 :return: """ # 将请求的url路径进行url编码 # values = request.path values = '/recharge/open_ability/pay/phone/create' str_encode_head = urllib.quote_plus(values) # 把除sign外的参数按key升序排序 keys = sorted(params.keys()) # 排序后的参数(key=value)用&拼接起来 sing_str = '' for key in keys: sing_str += str(key) + '=' + str(params[key]) + '&' sign_str = sing_str[:-1] # 进行URL编码 str_encode_param = urllib.quote(sign_str) # 将HTTP请求方式、url、url编码的参数拼接 str_method = 'POST' str_in_sign = str_method + '&' + str_encode_head + '&' + str_encode_param return str_in_sign def get_sha256(sign_str): """ sha256算法加密 :param sign_str: 待加密串 :return: """ hash_ = SHA256.new() hash_.update(sign_str) hash_.digest() return hash_ def st_generation_signature(str_sign, private): """ sha256生成签名值,rsa生成签名转为base64 :param str_sign: sha256摘要后的源串 :param private: 私钥 :return: """ private_key = RSA.importKey(private) sign_str = PKCS1_v1_5.new(private_key).sign(str_sign) sign = base64.b64encode(sign_str) return sign def check_open_ability_sign(req_data, sign, public_key): """ 验证开放能力报文中的sign加密是否正确 :param req_data:源串 :param sign: 用户所传签名 :param public_key:用户提供之公钥 :return: """ flag = False try: # 1. 对签名源串进行sha256计算,生成sha256摘要 sha256_sign = get_sha256(req_data) print "sha256为:", sha256_sign.hexdigest() # logger.debug("对签名源串进行sha256计算结果:%s" % sha256_sign) # 2. 对源签名进行BASE64解编码 decode_sign = base64.decodestring(sign) print 'base64编码为:', decode_sign # logger.debug("对源签名进行BASE64解编码:%s" % decode_sign) # 3. 获取公钥 begin = "-----BEGIN PUBLIC KEY----- " end = " -----END PUBLIC KEY-----" public_key = RSA.importKey(begin + public_key + end) print '公钥为:', public_key # logger.debug("public_key:%s" % public_key) # 4. 使用RSA的公钥对签名进行验证 verifier = PKCS1_v1_5.new(public_key) flag = verifier.verify(sha256_sign, decode_sign) # logger.debug("效验结果为:%s" % flag) except Exception as e: # logger.error('func: [check_open_ability_sign] ERROR' + e.message + ' ' + traceback.format_exc()) print(e.message + ' ' + traceback.format_exc()) return flag if __name__ == '__main__': # 生成签名:构建源串--->sha256生成摘要--->生成签名 data = {"firstReqTime": "2019-11-22 10:32:43", "merchantId": "100120191121145133325008", "payAmount": 500, "platFormId": "117", "rechargeAmount": 500, "rechargeNumber": "13332870007", "rechargeType": "1", "redirectingUrl": "https://www.114yiyuanwz.com", "reqTime": "2019-11-22 10:32:43", "sysCode": "S21720", "transactionId": "1574389963702"} # 测试用私钥 # private = """-----BEGIN RSA PRIVATE KEY----- # MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMnGO1a9s1berQTMOv7+zcfUwXSjx99InuS2mZP7YmBtn744JgIuwowO6kOoOMaeEifAfxwohdZwNw4TDyjxJoGC4WtQUE7EK5j0GV0a1ftbmqIN/lg3w45Bmkk7aAFk0RuB0uXybDTUT/HfrRy9/x1m6d1iHyn+27EdO+B7ONP9AgMBAAECgYAjiKcLlBXgvw9eUG81V/86aXP2TB+XaW0eHzA1uOguzi97Kt06tixpyPilmJsDE3RkDsjz1wkW5iUz89RQJAPhK+2ckD24nodXsKGY69g55dCIrPsjk6yu4WVaLcB+RKEFCECvzf7YbcjttifnDHya6V8Kx+s0Dw3WCP9yYFNUOwJBAOkA0d7e11UgkaXkTzgbY3QnPPQwqbLYow2PxdhDxeeGyGAqEFwiZ1YPQzIxhtDWK/AFNJAnFNK1T9uTyUWxhHcCQQDdsF4L0MIqoI5D64jkBe+vDro7AEwNM7Q0RNBaOJU1SPUASJn+hhSt/SzRckmPbnL3u0caeoGnNiMtD+ZT3gwrAkAM4ma4lEoEAxEKw10+FQWi3qiYODiqEyCxF0oxc032R5W8+5Z8AcsFD0L/+40g7zbuxtrpPcABBtWrprhyiiZxAkEAyXXucWRcH2ra/mQ8eaPfZkHHAblKY7D58YobofHLvqm3ZHOV5lSo1FjAcvIeYUcpGXJKsohj7LXpD5lkYhDnEwJATgeuq5y23oCrcS4iEYQVmPsvTv8/IubFNozdUc88a38SR+bNDTkbOr5hR0c0ayrp3Omj9DLFbmUkMaIx3GUJZA== # -----END RSA PRIVATE KEY----- # """ # 广东提供私钥 private = """-----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQCUB0e9yUv9en2O0qjcpO4OLUvAJ3lNz8qvULSvbnAA2ZfQemvx wFX9776iOUC2MFLBi9nO/hifrm933nyD+6ScVcD7NfJrKm7WdQRtQi1aYaghqJFD B7ydK05DS/BNEp8+YQzQ6X7zthld76CnXrZoVKmnbZq6cHOL0DnKSWnw8QIDAQAB AoGACu4Krwm48atkr/IAA+KtrSBNEpAXldY86fr0jGuEG5v1aLBRXhVMhCZ6lfHS RGGHCsFvwKfkW43+rwQff4NKISATirK/6RBGtd+Zvh4zSPRBoL8AfQm1EYfE+qQI mwNoKxkowvj0wn6Gk1TfbUUiJGc/1XkL725GO96DVnRjtS0CQQDXLUl3FPf5FkO/ Jm0AdEyg0+7yfjwqYyp/+osRTCU8oGTKeA0Btiv4RQJR4JCqc0uNtxbMrj+ZwgDw UHpzRfW7AkEAsBy57iDpbBSwoyjf1HSxubWDkT23w3lWDpmVXXBOxbEOGqK5jR8z YpE7HBi/VLJXDlrMri5RxkIewNiYl91TQwJAYq66SoqrTukPGNMeml675eZMZ5nN LgNcsmTM8pnhWfSVROXZ0Tci4zGC5tn+fq1xsQSOyEABmxqGI7BE+CjVkQJAKzaR ROYcgKG/CfoQmiAcL/ZjFzNusO9H94MmDGxvV8DvNgfxwbgDMs9yEp3b7Ntp0yLi kGbbN+ungihjoPf04wJANMNUzlSGxjW9/NJlpstRDEmauUYh+Ou/suJaNUS1eDyL VOwyVRUbySEinI8rz4FLHc/+PeWa7OED4Gklb2FtTA== -----END RSA PRIVATE KEY-----""" req_sing = check_string(data).replace('//', '%2F%2F') print '源串为:', req_sing h = SHA256.new(req_sing) gn_sing = st_generation_signature(h, private) print "私钥加密生成签名为:" , gn_sing # 验签:生成源串--->sha256生成摘要--->base64解码所传签名--->公钥解密验签 data = {"firstReqTime": "2019-11-22 10:32:43", "merchantId": "100120191121145133325008", "payAmount": 500, "platFormId": "117", "rechargeAmount": 500, "rechargeNumber": "13332870007", "rechargeType": "1", "redirectingUrl": "https://www.114yiyuanwz.com", "reqTime": "2019-11-22 10:32:43", "sysCode": "S21720", "transactionId": "1574389963702"} # 测试用公钥 # dq_public = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJxjtWvbNW3q0EzDr+/s3H1MF0o8ffSJ7ktpmT+2JgbZ++OCYCLsKMDupDqDjGnhInwH8cKIXWcDcOEw8o8SaBguFrUFBOxCuY9BldGtX7W5qiDf5YN8OOQZpJO2gBZNEbgdLl8mw01E/x360cvf8dZundYh8p/tuxHTvgezjT/QIDAQAB" # 广东提供公钥 dq_public = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUB0e9yUv9en2O0qjcpO4OLUvAJ3lNz8qvULSvbnAA2ZfQemvxwFX9776iOUC2MFLBi9nO/hifrm933nyD+6ScVcD7NfJrKm7WdQRtQi1aYaghqJFDB7ydK05DS/BNEp8+YQzQ6X7zthld76CnXrZoVKmnbZq6cHOL0DnKSWnw8QIDAQAB" # 广东提供充值签名 # sing = 'N2VhNDc1MDQ1NzlmMjIzM2RiMDhjNWU2Njg2MDNlMTkyZjgzNmNmYTZkZGU1ZjNjODM1NDIxMTM4OTMxZGI0NGIzYjBkYjdlZGUzMTJjNTk4ZWZmNDhjYTgzMWNiMjFiMTllZmYzNWU5Y2EyNTNiM2Q0ZGI1NDFkNzBiN2M3M2NmOTdjNjZmM2E1Yzk1OGJkODgwOTllOGNmNTFkMmQxYmQwODg4ZjkyYzEyM2ZkZTViZDNkZDFkZjZmZWIxODAwY2QyMzEwMzVkODQ3ODA3MTVmNTkwZWI5YzVjZDg3MzBmN2RjMzg3NjhlNmYxM2RjOTZjMjIwYzc1ZTJmMDUyNA' req_sing = check_string(data).replace('//', '%2F%2F') print '源串为:', req_sing flag = check_open_ability_sign(req_sing, gn_sing, dq_public) # 测试用 # flag = check_open_ability_sign(req_sing, sing, dq_public) # 广东 print "结果:", flag
ps:一直没有放弃,我一直在修改bug的路上……