CURL请求报错‘failed to decrypt request’问题求助
问题分析与解决方案
1. 首要问题:Bash变量未正确展开
你的curl请求中,-d参数使用单引号包裹JSON内容,导致$output变量不会被Bash解析替换,实际发送给API的是字符串"$output"而非加密后的内容,这直接导致解密失败。
修复方法:
改用双引号包裹JSON(注意转义内部双引号),或用jq工具安全构造JSON(推荐,避免特殊字符破坏JSON格式):
方法1:转义双引号
#!/usr/bin/env bash output=$(openssl enc -aes-256-cbc -pass pass:xxxxxxx -in msg.txt -base64) curl -X POST \ "https://api.swing.tradesmartonline.in/api/v1/login-token" \ -H "Content-Type: application/json" \ -d "{\"data\":\"$output\",\"app\":\"APPLICATION_ID\"}"
方法2:用jq构造JSON(更可靠)
#!/usr/bin/env bash output=$(openssl enc -aes-256-cbc -pass pass:xxxxxxx -in msg.txt -base64) jq -n --arg encrypted_data "$output" --arg app_id "APPLICATION_ID" \ '{"data": $encrypted_data, "app": $app_id}' | curl -X POST \ "https://api.swing.tradesmartonline.in/api/v1/login-token" \ -H "Content-Type: application/json" \ -d @-
2. 加密参数不匹配(本地能解密但API不行)
本地能用openssl解密,是因为openssl会自动处理加密时添加的盐值(默认行为),但API端的解密逻辑可能未兼容这个默认行为,或使用了不同的加密参数。
可能的参数差异及调整:
- 盐值处理:openssl默认会在加密内容前添加盐值(解码后开头为
Salted__),如果API端未处理盐值,需添加-nosalt参数禁用加盐:output=$(openssl enc -aes-256-cbc -pass pass:xxxxxxx -in msg.txt -base64 -nosalt) - 密钥派生算法:openssl默认用MD5作为密钥派生函数(KDF),如果API端使用SHA256等其他算法,需指定
-md参数:output=$(openssl enc -aes-256-cbc -pass pass:xxxxxxx -in msg.txt -base64 -md sha256) - IV(初始化向量):CBC模式需要IV,openssl默认随机生成IV并和盐一起输出。如果API端要求固定IV,需手动指定
-iv参数(16字节,对应AES-256的块大小):output=$(openssl enc -aes-256-cbc -pass pass:xxxxxxx -in msg.txt -base64 -iv "0123456789abcdef") - 填充方式:openssl默认使用PKCS#7填充,需确认API端使用相同的填充规则,若API要求无填充,需添加
-nopad(但需确保明文长度是块大小的整数倍)。
3. Python请求的对应调整
如果用Python的requests和Crypto模块调用时也报错,同样需要注意:
- 确保JSON中的加密字符串正确传递,避免字符串转义错误;
- 对齐加密参数:和API端一致的盐值处理、密钥派生方式、IV、填充规则。
示例代码(需根据实际参数调整):
import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad import requests password = b"xxxxxxx" # AES-256需要32字节密钥,若密码不足需派生或补全,此处示例直接取前32字节 key = password.ljust(32)[:32] iv = b"0123456789abcdef" # 若API要求固定IV with open("msg.txt", "rb") as f: plaintext = f.read() cipher = AES.new(key, AES.MODE_CBC, iv) ciphertext = cipher.encrypt(pad(plaintext, AES.block_size)) encrypted_data = base64.b64encode(ciphertext).decode() response = requests.post( "https://api.swing.tradesmartonline.in/api/v1/login-token", json={"data": encrypted_data, "app": "APPLICATION_ID"} ) print(response.json())
内容的提问来源于stack exchange,提问作者Govardhan Reddy
相关产品推荐
相关产品推荐

