登录
原创

银行卡三要素核验(SM2+SM4国密加密版)- 聚合数据API调用Python示例

发布于 2026-01-07 阅读 115
  • 后端
  • Python
  • 聚合科技
原创

本代码示例基于gmssl-python实现。gmssl-python是GmSSL密码库 https://github.com/guanzhi/GmSSL 的Python语言封装.

使用前需要安装GmSSL密码库, 可以参考:https://github.com/guanzhi/GmSSL

安装依赖

如果你是通过uv管理的项目

uv add gmssl-python
uv add requests

如果你是通过pip管理的项目

pip install gmssl-python
pip install requests

银行卡核验接口SM2SM4加密请求示例

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
银行卡三要素核验(SM2+SM4加密版)- 聚合数据API调用示例
文档地址:https://www.juhe.cn/docs/api/id/207

本示例演示如何使用SM2和SM4加密算法调用银行卡三要素核验接口
加密流程:
1. 生成随机的SM4密钥和初始向量
2. 使用SM2公钥加密SM4密钥和初始向量
3. 使用SM4加密敏感业务参数
4. 发送加密后的数据到接口
"""

import base64
import os
from typing import Dict, Optional
from gmssl import Sm4Cbc, Sm2Key, DO_ENCRYPT
import requests


# ==================== 配置项 ====================
API_URL = "https://v.juhe.cn/verifybankcard3/queryEncrySm"
API_KEY = "15e304************"  # 请替换为您自己的API Key
PUBLIC_KEY_FILE = "sm2_public_key.pem"  # SM2公钥文件路径(联系聚合商务获取)


# ==================== 加密工具函数 ====================
def sm4_encrypt(sm4_key: bytes, sm4_iv: bytes, data: str) -> str:
    """
    使用SM4算法加密数据
    
    Args:
        sm4_key: SM4密钥(16字节)
        sm4_iv: SM4初始向量(16字节)
        data: 待加密的明文数据
    
    Returns:
        Base64编码的加密数据
    """
    sm4_enc = Sm4Cbc(sm4_key, sm4_iv, DO_ENCRYPT)
    encrypted = sm4_enc.update(data.encode('utf-8'))
    encrypted += sm4_enc.finish()
    return base64.b64encode(encrypted).decode('utf-8')


def sm2_encrypt_key(public_key_path: str, data: bytes) -> str:
    """
    使用SM2公钥加密数据
    
    Args:
        public_key_path: SM2公钥文件路径
        data: 待加密的数据
    
    Returns:
        Base64编码的加密数据
    """
    public_key = Sm2Key()
    public_key.import_public_key_info_pem(public_key_path)
    encrypted = public_key.encrypt(data)
    return base64.b64encode(encrypted).decode('utf-8')


# ==================== 主要业务逻辑 ====================
def verify_bank_card(
    realname: str,
    idcard: str,
    bankcard: str,
    mobile: str,
    api_key: str = API_KEY,
    api_url: str = API_URL
) -> Optional[Dict]:
    """
    银行卡三要素核验
    
    Args:
        realname: 真实姓名
        idcard: 身份证号码
        bankcard: 银行卡号
        mobile: 手机号码
        api_key: API密钥
        api_url: API接口地址
    
    Returns:
        API响应的JSON数据,失败时返回None
    """
    try:
        # 步骤1: 生成随机的SM4密钥和初始向量(各16字节)
        sm4_key = os.urandom(16)
        sm4_iv = os.urandom(16)
        print("=" * 60)
        print("步骤1: 生成SM4密钥和初始向量")
        print(f"SM4 Key (hex): {sm4_key.hex()}")
        print(f"SM4 IV (hex):  {sm4_iv.hex()}")
        
        # 步骤2: 使用SM2公钥加密SM4密钥和初始向量
        print("\n步骤2: 使用SM2公钥加密SM4密钥和初始向量")
        encrypted_sm4_key = sm2_encrypt_key(PUBLIC_KEY_FILE, sm4_key)
        encrypted_sm4_iv = sm2_encrypt_key(PUBLIC_KEY_FILE, sm4_iv)
        print(f"加密后的SM4 Key: {encrypted_sm4_key[:50]}...")
        print(f"加密后的SM4 IV:  {encrypted_sm4_iv[:50]}...")
        
        # 步骤3: 使用SM4加密敏感业务参数
        print("\n步骤3: 使用SM4加密业务参数")
        encrypted_realname = sm4_encrypt(sm4_key, sm4_iv, realname)
        encrypted_idcard = sm4_encrypt(sm4_key, sm4_iv, idcard)
        encrypted_bankcard = sm4_encrypt(sm4_key, sm4_iv, bankcard)
        encrypted_mobile = sm4_encrypt(sm4_key, sm4_iv, mobile)
        print(f"姓名已加密: {encrypted_realname}")
        print(f"身份证已加密: {encrypted_idcard}")
        print(f"银行卡已加密: {encrypted_bankcard}")
        print(f"手机号已加密: {encrypted_mobile}")
        
        # 步骤4: 构造请求参数
        print("\n步骤4: 构造请求参数")
        request_params = {
            'key': api_key,
            'realname': encrypted_realname,
            'idcard': encrypted_idcard,
            'bankcard': encrypted_bankcard,
            'mobile': encrypted_mobile,
            'sm4Key': encrypted_sm4_key,
            'sm4Iv': encrypted_sm4_iv,
        }
        
        # 步骤5: 发送POST请求
        print("\n步骤5: 发送请求到API")
        print(f"请求地址: {api_url}")
        response = requests.post(api_url, data=request_params, timeout=10)
        response.raise_for_status()
        
        # 步骤6: 解析响应
        print("\n步骤6: 解析API响应")
        print("=" * 60)
        response_data = response.json()
        
        if response_data.get('error_code') == 0:
            print("✓ 请求成功")
            print(f"响应结果: {response_data}")
        else:
            print("✗ 请求失败")
            print(f"错误代码: {response_data.get('error_code')}")
            print(f"错误原因: {response_data.get('reason')}")
        
        print("=" * 60)
        return response_data
        
    except requests.exceptions.RequestException as e:
        print(f"✗ 网络请求失败: {e}")
        return None
    except FileNotFoundError:
        print(f"✗ 公钥文件不存在: {PUBLIC_KEY_FILE}")
        print("提示: 请联系聚合商务获取SM2公钥文件")
        return None
    except Exception as e:
        print(f"✗ 发生错误: {e}")
        return None


def main():
    """
    主函数 - 演示如何调用银行卡三要素核验接口
    """
    print("\n银行卡三要素核验(SM2+SM4加密版)- 示例程序")
    print("=" * 60)
    
    # 示例数据(请替换为真实数据进行测试)
    test_data = {
        'realname': '董先生',
        'idcard': '330329198901010202',
        'bankcard': '6216606101012341234',
        'mobile': '18913511234'
    }
    
    print("测试数据(明文):")
    for key, value in test_data.items():
        print(f"  {key}: {value}")
    print()
    
    # 调用接口
    result = verify_bank_card(**test_data)
    
    if result:
        print("\n接口调用完成!")
    else:
        print("\n接口调用失败,请检查配置和网络连接")


if __name__ == "__main__":
    main()

评论区

DDwyane
23粉丝

我饿了,要睡觉了~

0

0

4

举报