Python编程-RSA非对称加密解密

# 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-----\n"
        end = "\n-----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 + '\n' + traceback.format_exc())
        print(e.message + '\n' + 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的路上……

你可能感兴趣的:(Python编程-RSA非对称加密解密)