微信支付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\n%s\n%s\n%s\n%s\n' % (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\n%s\n%s\n' % (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包。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM