zoukankan      html  css  js  c++  java
  • 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-----
    "
            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的路上……

  • 相关阅读:
    Ceph的参数mon_osd_down_out_subtree_limit细解
    java:警告:[unchecked] 对作为普通类型 java.util.HashMap 的成员的put(K,V) 的调用未经检查
    Java 原始类型JComboBox的成员JComboBox(E())的调用 未经过检查
    Android draw Rect 坐标图示
    不用快捷键就能使用Eclipse的自动完成功能
    Java 窗体居中 通用代码
    Java文件复制删除操作合集
    Java Toolkit类用法
    DEVEXPRESS 破解方法
    如何使用Java执行cmd命令
  • 原文地址:https://www.cnblogs.com/sunxiuwen/p/11911508.html
Copyright © 2011-2022 走看看