通过Wallester API解密银行卡数据遇阻,寻求技术协助
解决Wallester API银行卡号解密失败问题
我尝试通过Wallester API获取银行卡数据,但解密环节持续报错,在线工具无法提供有效帮助,官方支持也没给出可行方案。附上我的Python代码,求有相关开发经验的人帮忙排查问题:
import json import base64 import jwt import requests import rsa import time def get_encrypted_card_number(api_key, rsa_public_key, rsa_private_key, card_id): # Generate the JWT token jwt_private_key = rsa_private_key.encode() timestamp = int(time.time()) claims = { "api_key": api_key, "ts": timestamp } jwt_token = jwt.encode(claims, jwt_private_key, algorithm="RS256") request_data = { 'public_key': base64.b64encode(rsa_public_key.encode()).decode() } headers = { 'Authorization': "Bearer " + jwt_token, 'Content-Type': 'application/json' } url = f"https://api-frontend.wallester.com/v1/cards/{card_id}/encrypted-card-number" # Send the API request response = requests.post(url, headers=headers, data=json.dumps(request_data)) response_data = response.json() if response.status_code != 200: raise Exception("API request failed") response_data = response.json() res = response_data['encrypted_card_number'] res = res.replace("-----BEGIN CardNumber MESSAGE-----", "") res = res.replace("-----END CardNumber MESSAGE-----", "") res = res.replace("\n", "") print(res) encrypted_card_number = base64.b64decode(res.encode()) # Decrypt the card number private_key = rsa.PrivateKey.load_pkcs1(rsa_private_key.encode()) decrypted_card_number = rsa.decrypt(encrypted_card_number, private_key).decode() return decrypted_card_number # Example usage api_key = "" with open("private.pem", "r") as f: rsa_private_key = f.read() with open("public.pem", "r") as f: rsa_public_key = f.read() card_id = "ce7b54a6-8165-49e1-97b2-bca7af5abaa5" decrypted_card_number = get_encrypted_card_number(api_key, rsa_public_key, rsa_private_key, card_id) print(f"Decrypted card number: {decrypted_card_number}")
排查与解决步骤
- 切换RSA填充方式
金融类API普遍使用更安全的OAEP填充,而rsa库默认的decrypt方法用的是PKCS#1 v1.5,这大概率是解密失败的核心原因。替换解密代码为OAEP方式:
from rsa.pkcs1 import oaep_decrypt, DecryptionError # ... 其他代码保持不变 # 替换原解密逻辑 decrypted_card_number = oaep_decrypt(private_key, encrypted_card_number).decode()
- 优化响应解析
原代码重复调用response.json(),直接改成一次解析即可:
response_data = response.json() if response.status_code != 200: raise Exception(f"API请求失败: {response_data.get('message', '未知错误')}")
- 验证JWT有效性
确保生成的JWT签名正确,可添加验证逻辑排查:
# 在生成JWT后添加 decoded_jwt = jwt.decode(jwt_token, rsa_public_key, algorithms=["RS256"], options={"verify_signature": True}) print("JWT验证通过:", decoded_jwt)
- 检查公钥传递格式
部分API要求传递清理后的公钥(去除头尾标签和换行)再做base64编码,调整公钥处理逻辑:
cleaned_public_key = rsa_public_key.replace("-----BEGIN PUBLIC KEY-----", "") cleaned_public_key = cleaned_public_key.replace("-----END PUBLIC KEY-----", "").replace("\n", "") request_data = { 'public_key': base64.b64encode(cleaned_public_key.encode()).decode() }
- 捕获具体错误信息
替换笼统的异常,捕获rsa库的特定解密错误,方便定位问题:
try: private_key = rsa.PrivateKey.load_pkcs1(rsa_private_key.encode()) decrypted_card_number = oaep_decrypt(private_key, encrypted_card_number).decode() except DecryptionError as e: raise Exception(f"解密失败: {str(e)}")
修改后的完整代码
import json import base64 import jwt import requests import rsa from rsa.pkcs1 import oaep_decrypt, DecryptionError import time def get_encrypted_card_number(api_key, rsa_public_key, rsa_private_key, card_id): # 生成JWT Token jwt_private_key = rsa_private_key.encode() timestamp = int(time.time()) claims = { "api_key": api_key, "ts": timestamp } jwt_token = jwt.encode(claims, jwt_private_key, algorithm="RS256") # 验证JWT有效性(可选) decoded_jwt = jwt.decode(jwt_token, rsa_public_key, algorithms=["RS256"], options={"verify_signature": True}) print("JWT验证通过:", decoded_jwt) # 清理公钥并编码 cleaned_public_key = rsa_public_key.replace("-----BEGIN PUBLIC KEY-----", "") cleaned_public_key = cleaned_public_key.replace("-----END PUBLIC KEY-----", "").replace("\n", "") request_data = { 'public_key': base64.b64encode(cleaned_public_key.encode()).decode() } headers = { 'Authorization': f"Bearer {jwt_token}", 'Content-Type': 'application/json' } url = f"https://api-frontend.wallester.com/v1/cards/{card_id}/encrypted-card-number" # 发送请求 response = requests.post(url, headers=headers, data=json.dumps(request_data)) response_data = response.json() if response.status_code != 200: raise Exception(f"API请求失败: {response_data.get('message', '未知错误')}") # 处理加密卡号 encrypted_card_data = response_data['encrypted_card_number'] encrypted_card_data = encrypted_card_data.replace("-----BEGIN CardNumber MESSAGE-----", "") encrypted_card_data = encrypted_card_data.replace("-----END CardNumber MESSAGE-----", "").replace("\n", "") encrypted_card_number = base64.b64decode(encrypted_card_data.encode()) # 解密(使用OAEP填充) try: private_key = rsa.PrivateKey.load_pkcs1(rsa_private_key.encode()) decrypted_card_number = oaep_decrypt(private_key, encrypted_card_number).decode() except DecryptionError as e: raise Exception(f"解密失败: {str(e)}") return decrypted_card_number # 示例使用 if __name__ == "__main__": api_key = "你的API密钥" with open("private.pem", "r") as f: rsa_private_key = f.read() with open("public.pem", "r") as f: rsa_public_key = f.read() card_id = "ce7b54a6-8165-49e1-97b2-bca7af5abaa5" try: decrypted_card_number = get_encrypted_card_number(api_key, rsa_public_key, rsa_private_key, card_id) print(f"解密后的卡号: {decrypted_card_number}") except Exception as e: print(f"错误: {str(e)}")
内容的提问来源于stack exchange,提问作者Jakub Štellner
相关产品推荐
相关产品推荐

