diff --git a/dsLightRag/JiMeng/JmTxt2Img.py b/dsLightRag/JiMeng/JmTxt2Img.py index a74bf869..18b9021e 100644 --- a/dsLightRag/JiMeng/JmTxt2Img.py +++ b/dsLightRag/JiMeng/JmTxt2Img.py @@ -3,6 +3,9 @@ import os import time import base64 +from JiMeng.Kit.JmCommon import JmCommon +from JiMeng.Kit.JmErrorCode import JmErrorCode + class JmTxt2Img: action = "CVProcess" diff --git a/dsLightRag/JiMeng/Kit/JmCommon.py b/dsLightRag/JiMeng/Kit/JmCommon.py index 4b1288d5..bc1a73f2 100644 --- a/dsLightRag/JiMeng/Kit/JmCommon.py +++ b/dsLightRag/JiMeng/Kit/JmCommon.py @@ -5,7 +5,6 @@ import os import time from datetime import datetime, timezone import requests -import base64 class JmCommon: @@ -26,58 +25,26 @@ class JmCommon: base_path = os.path.join(project_root, "src", "main", "python", "com", "dsideal", "aiSupport", "Util", "JiMeng", "Example") @staticmethod - def sign_string_encoder(source): - """URL编码字符串,用于签名""" - if source is None: - return None - - # 不需要编码的字符 - safe_chars = set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~") - result = [] - - for char in source: - if char in safe_chars: - result.append(char) - elif char == ' ': - result.append("%20") - else: - # 对其他字符进行URL编码 - result.append(f"%{ord(char):02X}") - - return ''.join(result) - - @staticmethod - def hash_sha256(content): - """计算内容的SHA256哈希值""" - try: - md = hashlib.sha256() - md.update(content) - return md.hexdigest() - except Exception as e: - raise Exception(f"计算哈希值失败: {str(e)}") - - @staticmethod - def hmac_sha256(key, content): + def sign(key, msg): """使用HMAC-SHA256算法计算消息认证码""" - try: - h = hmac.new(key, content.encode('utf-8'), hashlib.sha256) - return h.digest() - except Exception as e: - raise Exception(f"计算HMAC-SHA256失败: {str(e)}") + return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest() @staticmethod - def gen_signing_secret_key_v4(date, region, service): + def get_signature_key(key, date_stamp, region_name, service_name): """生成V4版本的签名密钥""" - try: - # 解码SK (Base64) - sk_bytes = base64.b64decode(JmCommon.sk) - k_date = JmCommon.hmac_sha256(sk_bytes, date) - k_region = JmCommon.hmac_sha256(k_date, region) - k_service = JmCommon.hmac_sha256(k_region, service) - k_signing = JmCommon.hmac_sha256(k_service, "request") - return k_signing - except Exception as e: - raise Exception(f"生成签名密钥失败: {str(e)}") + k_date = JmCommon.sign(key.encode('utf-8'), date_stamp) + k_region = JmCommon.sign(k_date, region_name) + k_service = JmCommon.sign(k_region, service_name) + k_signing = JmCommon.sign(k_service, 'request') + return k_signing + + @staticmethod + def format_query(parameters): + """格式化查询参数""" + request_parameters_init = '' + for key in sorted(parameters): + request_parameters_init += key + '=' + str(parameters[key]) + '&' + return request_parameters_init[:-1] if request_parameters_init else '' @staticmethod def do_request(method, query_list, body, action): @@ -86,59 +53,49 @@ class JmCommon: if body is None: body = b'' - # 计算请求体的SHA256哈希值 - x_content_sha256 = JmCommon.hash_sha256(body) - - # 格式化日期时间,用于请求头 - x_date = date.strftime("%Y%m%dT%H%M%SZ") - short_x_date = x_date[:8] # 提取日期部分,用于凭证范围 - - content_type = "application/json" - sign_header = "host;x-date;x-content-sha256;content-type" + # 格式化日期时间 + current_date = date.strftime("%Y%m%dT%H%M%SZ") + date_stamp = date.strftime("%Y%m%d") # 构建查询参数字符串 real_query_list = query_list.copy() if query_list else {} real_query_list["Action"] = action real_query_list["Version"] = JmCommon.version + canonical_querystring = JmCommon.format_query(real_query_list) - # 排序查询参数 - sorted_query = sorted(real_query_list.items()) - query_sb = [] - for key, value in sorted_query: - encoded_key = JmCommon.sign_string_encoder(key) - encoded_value = JmCommon.sign_string_encoder(str(value)) - query_sb.append(f"{encoded_key}={encoded_value}") - query_string = "&" .join(query_sb) + # 计算请求体哈希值 + if isinstance(body, bytes): + body_str = body.decode('utf-8') + else: + body_str = str(body) + payload_hash = hashlib.sha256(body_str.encode('utf-8')).hexdigest() - # 构建规范请求字符串,用于签名 - canonical_string = f"{method}\n{JmCommon.path}\n{query_string}\n" - canonical_string += f"host:{JmCommon.host}\n" - canonical_string += f"x-date:{x_date}\n" - canonical_string += f"x-content-sha256:{x_content_sha256}\n" - canonical_string += f"content-type:{content_type}\n\n" - canonical_string += f"{sign_header}\n{x_content_sha256}" + # 设置请求头相关信息 + content_type = "application/json" + signed_headers = 'content-type;host;x-content-sha256;x-date' + canonical_headers = f'content-type:{content_type}\nhost:{JmCommon.host}\nx-content-sha256:{payload_hash}\nx-date:{current_date}\n' - # 计算规范请求字符串的哈希值 - hash_canonical_string = JmCommon.hash_sha256(canonical_string.encode('utf-8')) + # 构建规范请求字符串 + canonical_request = f'{method}\n{JmCommon.path}\n{canonical_querystring}\n{canonical_headers}\n{signed_headers}\n{payload_hash}' - # 构建凭证范围和签名字符串 - credential_scope = f"{short_x_date}/{JmCommon.region}/{JmCommon.service}/request" - sign_string = f"HMAC-SHA256\n{x_date}\n{credential_scope}\n{hash_canonical_string}" + # 构建签名字符串 + algorithm = 'HMAC-SHA256' + credential_scope = f'{date_stamp}/{JmCommon.region}/{JmCommon.service}/request' + string_to_sign = f'{algorithm}\n{current_date}\n{credential_scope}\n{hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()}' # 生成签名密钥并计算签名 - sign_key = JmCommon.gen_signing_secret_key_v4(short_x_date, JmCommon.region, JmCommon.service) - signature = hmac.new(sign_key, sign_string.encode('utf-8'), hashlib.sha256).hexdigest() + signing_key = JmCommon.get_signature_key(JmCommon.sk, date_stamp, JmCommon.region, JmCommon.service) + signature = hmac.new(signing_key, string_to_sign.encode('utf-8'), hashlib.sha256).hexdigest() # 构建URL - url = f"{JmCommon.schema}://{JmCommon.host}{JmCommon.path}?{query_string}" + url = f'{JmCommon.schema}://{JmCommon.host}{JmCommon.path}?{canonical_querystring}' # 设置请求头 headers = { - "Host": JmCommon.host, - "X-Date": x_date, - "X-Content-Sha256": x_content_sha256, - "Content-Type": content_type, - "Authorization": f"HMAC-SHA256 Credential={JmCommon.ak}/{credential_scope}, SignedHeaders={sign_header}, Signature={signature}" + "X-Date": current_date, + "Authorization": f'{algorithm} Credential={JmCommon.ak}/{credential_scope}, SignedHeaders={signed_headers}, Signature={signature}', + "X-Content-Sha256": payload_hash, + "Content-Type": content_type } # 发送请求 diff --git a/dsLightRag/JiMeng/Kit/__pycache__/JmCommon.cpython-310.pyc b/dsLightRag/JiMeng/Kit/__pycache__/JmCommon.cpython-310.pyc new file mode 100644 index 00000000..833b7e35 Binary files /dev/null and b/dsLightRag/JiMeng/Kit/__pycache__/JmCommon.cpython-310.pyc differ