base64_encode(hash_hmac('sha1',$message, $accessKey, true))

本文探讨了在API安全认证中,由于PHP与JAVA在处理accessKey中的空格问题,导致hmac_sha1签名不一致的现象。揭示了数据库中额外空格对签名算法的影响。

一个空格引发的血案

服务端是由PHP实现的,客户端是由JAVA实现的;
API安全认证协议中要求使用hmac_sha1方法对信息进行编码
但是两边生成的签名一直不一致

php

base64_encode(hash_hmac('sha1',$message, $accessKey, true))

java

Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes('utf8'), 'UTF-8');
mac.init(keySpec);
 return mac.doFinal(baseString.getBytes('utf8'));

废话
两边生成的签名最初是一样的,后来不知道啥时候开始就一直不一致,最初一直在找是不是编码的问题,传的数据是不是一样,打印日志看看数据没有问题啊?最后发现是空格的问题,accessKey值是从数据库查出来的,数据库中数据有个空格!!!这个空格还是自己修改数据弄进去的,就是PHP代码中accessKey是

1fd7c358842b481b9a07e34411baac3c

&

呵呵呵呵,一样了才怪

import base64 import hashlib import hmac import time import requests from Crypto.Cipher import AES from Crypto.Util.Padding import unpad class ApiCaller: TOKEN_URL = "https://drs.dsjfzj.cq.cegn:11007/apisix/token" CACHED_TOKEN_MAP = {} def main(self): try: access_key = "BCDSGA_20b112c5a9d45bd38f7e5efe72be4fb3" secret_key = "BCDSGS_35c0eee59372a29842973c12d4e71d6b" apiCaller = ApiCaller() url = "https://drs.dsjfzj.cq.cegn:11007/restapi/prod/IC50000020250616000140/xdata/tbl/api/execute/1a929ab0-467c-490f-91c7-17533d3e8838" method = "POST" token = apiCaller.get_token(access_key, secret_key) param = {} result = apiCaller.call_url(url, method, token, param) print("call result:", result) except Exception as e: print("call failed:", str(e)) def call_url(self, url, method, token, param): headers = { "X-ACCESS-TOKEN": token, "Content-Type": "application/json" } response = requests.request(method, url, headers=headers, json=param) response.raise_for_status() return response.json() def get_token(self, access_key, secret_key): cached_token = self.CACHED_TOKEN_MAP.get(access_key) if cached_token and cached_token.get("expire_time", 0) > int(time.time()) + 60: return cached_token.get("token", "") token_data = self.do_get_token(access_key, secret_key) self.CACHED_TOKEN_MAP[access_key] = token_data return token_data.get("token", "") def do_get_token(self, access_key, secret_key): timestamp = int(time.time()) # 请求参数 params = {'access_key': access_key, 'timestamp': timestamp} sort_params = dict(sorted(params.items(), key=lambda x: x[0])) # 按照字典对参数进行排序 sign_string = '&'.join([f"{key}={value}" for key, value in sort_params.items()]) # 对参数进行加密 hmac_obj = hmac.new(secret_key.encode('utf-8'), sign_string.encode('utf-8'), hashlib.sha256) signature = hmac_obj.hexdigest() query_params = {"access_key": access_key, "timestamp": timestamp, "signature": signature} response = requests.get(self.TOKEN_URL, query_params) response.raise_for_status() return response.json() def decrypt_field(self, encrypt, secret_key): if not encrypt: return encrypt aes_key = secret_key[-16:].encode("utf-8") cipher = AES.new(aes_key, AES.MODE_CBC, aes_key) decrypted = cipher.decrypt(base64.b64decode(encrypt)) decrypted = unpad(decrypted, AES.block_size) return decrypted.decode("utf-8") if __name__ == "__main__": apiCaller = ApiCaller() apiCaller.main()对以上代码在apipost软件上测试,写出具体详细步骤
最新发布
07-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值