Python调用JS解密代码报错的排查与解决
在使用Python调用JavaScript代码进行解密时,即使参数正确,也可能遇到execjs.ProgramError。本文分析一个案例,并提供解决方案。
问题描述:
程序使用execjs库执行一段使用crypto-js库进行AES解密的JavaScript代码。尽管设置了UTF-8编码,但仍出现execjs.ProgramError。
Python代码片段:
import requests import execjs import sys import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') # ... (requests代码省略) ... try: response_text = response.content.decode('utf-8') decrypted_text = execjs.compile(open('./decrypt.js', 'r', encoding='utf-8').read()).call('decrypt', response_text) print("解密结果:", decrypted_text) except execjs.ProgramError as e: print(f"JavaScript错误: {e}") # ... (其他异常处理省略) ...
JavaScript代码片段:
const CryptoJS = require('crypto-js'); function decrypt(t) { let key = 'rewin-swhysc1234'; let keyBytes = CryptoJS.enc.Utf8.parse(key); let decrypted = CryptoJS.AES.decrypt(t, keyBytes, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); return decrypted.toString(CryptoJS.enc.Utf8); }
问题分析与解决方案:
问题可能源于execjs与crypto-js的兼容性,以及execjs处理加密数据的限制。execjs并非直接运行JavaScript,而是通过Node.js等引擎,这可能导致兼容性问题。
建议:使用Python原生加密库替代execjs和crypto-js。 Python的Crypto库提供AES加密解密功能,避免兼容性问题。
Python原生加密库解决方案:
from Crypto.Cipher import AES import base64 def decrypt(ciphertext): key = b'rewin-swhysc1234' cipher = AES.new(key, AES.MODE_ECB) plaintext = cipher.decrypt(base64.b64decode(ciphertext)) return plaintext.decode('utf-8')
此Python函数使用Crypto.Cipher.AES进行AES解密,并用base64处理Base64编码的密文。这更直接高效,避免兼容性问题。
额外注意事项:
- 输入参数校验: JavaScript代码应增强输入参数t的校验,避免空值或格式错误导致解密失败。
- 异常处理: 完善Python代码的异常处理,例如处理base64.b64decode可能抛出的异常。
通过使用Python原生加密库,可以提高代码效率和稳定性,并解决execjs和crypto-js兼容性问题。 记住始终对输入数据进行严格的验证和处理,以确保程序的健壮性。