zoukankan      html  css  js  c++  java
  • 微信支付v3版几个重难点(签名、验签、加密、解密)的python实现

    背景介绍

    v3版微信支付通过商户证书和平台证书加强了安全性,也大幅提高了开发难度,python版sdk包wechatpayv3内部封装了安全性相关的签名、验签、加密和解密工作,降低了开发难度。下面几个特性的实现,更方便了开发者。

    1. 平台证书自动更新,无需开发者关注平台证书有效性,无需手动下载更新;
    2. 支持本地缓存平台证书,初始化时指定平台证书保存目录即可。
    3. 敏感信息直接传入明文参数,SDK内部自动加密,无需手动处理。

    在这里将sdk内部几个涉及到安全性的方法单独抽出来结合官方文档对照一下,方便大家更直观的理解,有兴趣探究sdk内部实现细节的同学可以了解一下,一般应用的无需关注,直接调用sdk包即可。

    构造签名信息

    对应v3版微信支付api文档的签名生成部分。

    def build_authorization(path,
                            method,
                            mchid,
                            serial_no,
                            mch_private_key,
                            data=None,
                            nonce_str=None):
        timeStamp = str(int(time.time()))
        nonce_str = nonce_str or ''.join(str(uuid.uuid4()).split('-')).upper()
        body = json.dumps(data) if data else ''
        sign_str = '%s
    %s
    %s
    %s
    %s
    ' % (method, path, timeStamp, nonce_str, body)
        signature = rsa_sign(private_key=mch_private_key, sign_str=sign_str)
        authorization = 'WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",signature="%s",timestamp="%s",serial_no="%s"' % (mchid, nonce_str, signature, timeStamp, serial_no)
        return authorization
    

    验证签名

    对应v3版微信支付api文档的签名验证部分。

    def rsa_verify(timestamp, nonce, body, signature, certificate):
        sign_str = '%s
    %s
    %s
    ' % (timestamp, nonce, body)
        public_key = certificate.public_key()
        message = sign_str.encode('UTF-8')
        signature = b64decode(signature)
        try:
            public_key.verify(signature, sign_str.encode('UTF-8'), PKCS1v15(), SHA256())
        except InvalidSignature:
            return False
        return True
    

    回调信息解密

    对应v3版微信支付api文档的证书和回调报文解密部分。

    def aes_decrypt(nonce, ciphertext, associated_data, apiv3_key):
        key_bytes = apiv3_key.encode('UTF-8')
        nonce_bytes = nonce.encode('UTF-8')
        associated_data_bytes = associated_data.encode('UTF-8')
        data = b64decode(ciphertext)
        aesgcm = AESGCM(key=key_bytes)
        try:
            result = aesgcm.decrypt(nonce=nonce_bytes, data=data, associated_data=associated_data_bytes).decode('UTF-8')
        except InvalidTag:
            result = None
        return result
    

    敏感信息加密

    对应v3版微信支付api文档的敏感信息加解密的加密部分。

    def rsa_encrypt(text, certificate):
        data = text.encode('UTF-8')
        public_key = certificate.public_key()
        cipherbyte = public_key.encrypt(
            plaintext=data,
            padding=OAEP(mgf=MGF1(algorithm=SHA1()), algorithm=SHA1(), label=None)
        )
        return b64encode(cipherbyte).decode('UTF-8')
    

    敏感信息解密

    对应v3版微信支付api文档的敏感信息加解密的解密部分。

    def rsa_decrypt(ciphertext, private_key):
        data = private_key.decrypt(ciphertext=b64decode(ciphertext), padding=OAEP(mgf=MGF1(algorithm=SHA1), algorithm=SHA1))
        result = data.decode('UTF-8')
        return result
    

    注意事项

    以上涉及到的几项签名如果计划抽出来单独使用,需要引入cryptography包。

  • 相关阅读:
    Java实现 计蒜客 拯救行动
    Java实现 计蒜客 拯救行动
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 173 二叉搜索树迭代器
    Java实现 LeetCode 173 二叉搜索树迭代器
    Visual Studio的SDK配置
    怎样使用CMenu类
    mfc menu用法一
  • 原文地址:https://www.cnblogs.com/minibear2000/p/15252174.html
Copyright © 2011-2022 走看看