You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32-S3上MicroPython实现AWS CloudWatch签名报错求助

AWS CloudWatch HTTPS上报日志InvalidSignatureException问题排查

在ESP32-S3上使用MicroPython开发项目,尝试通过HTTPS向AWS CloudWatch上报日志,生成AWS V4签名后,收到AWS返回的错误:

{"__type":"InvalidSignatureException","message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."}

签名生成代码

try:
    from uhashlib import sha256 as _sha256
except ImportError:
    print("Warning: not using uhashlib")
    from hashlib import sha256 as _sha256

import hmac_ltd as _hmac
import ubinascii as _ubinascii


def request_gen(
    access_key,
    secret_key,
    date_time_stamp,
    method="POST",
    region="us-east-1",
    body="",
    uri="",
):
    service = "logs"
    request_type = "aws4_request"
    algorithm = "AWS4-HMAC-SHA256"


    date_stamp = date_time_stamp[:8]

    return_dict = {}
    return_dict["host"] = f"{service}.{region}.amazonaws.com"
    return_dict["uri"] = "/"


    key = bytearray()
    key.extend(("AWS4" + secret_key).encode())
    print("key: ", key)
    kDate = _hmac.new(key, date_stamp, _sha256).digest()
    kRegion = _hmac.new(kDate, region, _sha256).digest()
    kService = _hmac.new(kRegion, service, _sha256).digest()
    kSigning = _hmac.new(kService, request_type, _sha256).digest()

    content_length = str(len(body))
    print(body)
    payload_hash = _ubinascii.hexlify(_sha256(body.encode("utf-8")).digest()).decode(
        "utf-8"
    )

    # make the string to sign
    canonical_querystring = ""  # no request params for logs

    canonical_headers_dict = {
        "content-type": "application/x-amz-json-1.1",
        "host": return_dict["host"],
        "x-amz-content-sha256": payload_hash,
        "x-amz-date": date_time_stamp,
        "x-amz-target": "Logs_20140328.PutLogEvents",
    }
    # Build the canonical headers string
    canonical_headers = "\n".join(
        f"{key}:{value}" for key, value in canonical_headers_dict.items()
    )
    # Get the sorted keys for signed_headers
    signed_headers = ";".join(
        sorted(key.lower() for key in canonical_headers_dict.keys())
    )

    canonical_request = (
        method
        + "\n"
        + return_dict["uri"]
        + "\n"
        + canonical_querystring
        + "\n"
        + canonical_headers
        + "\n"
        + signed_headers
        + "\n"
        + payload_hash
    )


    canonical_request_hash = _ubinascii.hexlify(
        _sha256(canonical_request.encode("utf-8")).digest()
    ).decode("utf-8")


    credential_scope = date_stamp + "/" + region + "/" + service + "/" + request_type
    string_to_sign = (
        algorithm
        + "\n"
        + date_time_stamp
        + "\n"
        + credential_scope
        + "\n"
        + canonical_request_hash
    )

    # generate the signature:
    signature = _hmac.new(kSigning, string_to_sign, _sha256).digest()
    signatureHex = _ubinascii.hexlify(signature).decode("utf-8")

    authorization_header = (
        algorithm
        + " "
        + "Credential="
        + access_key
        + "/"
        + credential_scope
        + ", "
        + "SignedHeaders="
        + signed_headers
        + ", "
        + "Signature="
        + signatureHex
    )

    return_dict["headers"] = {
        "authorization": authorization_header,
        "content-type": "application/x-amz-json-1.1",
        "host": return_dict["host"],
        "x-amz-content-sha256": payload_hash,
        "x-amz-date": date_time_stamp,
        "x-amz-target": "Logs_20140328.PutLogEvents",
    }

    return return_dict

请求输出

##########################################
canonical_request: 
POST
/

content-type:application/x-amz-json-1.1
host:logs.us-east-1.amazonaws.com
x-amz-target:Logs_20140328.PutLogEvents
x-amz-content-sha256:7dbe84657fbd1885f46b4d0d51a6b49be58c78db693af0fe85e335f28f6efefd
x-amz-date:20231125T183032Z
content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target
7dbe84657fbd1885f46b4d0d51a6b49be58c78db693af0fe85e335f28f6efefd
##########################################


string_to_sign: 
AWS4-HMAC-SHA256
20231125T183032Z
20231125/us-east-1/logs/aws4_request
62143e2e37c17f0122bfce2333c7523c78844be83a23df9c426ddf9109ee8584



signature: 
07685ab92b73a08ca828948e05251296f3a0bdc774f0bc904e8311064e8fc407
##########################################


BEGIN REQUEST++++++++++++++++++++++++++++++++++++

Request URL = https://logs.us-east-1.amazonaws.com

Request Headers = {"authorization": "AWS4-HMAC-SHA256 Credential=<ACCESS_KEY>/20231125/us-east-1/logs/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target, Signature=07685ab92b73a08ca828948e05251296f3a0bdc774f0bc904e8311064e8fc407", "x-amz-date": "20231125T183032Z", "x-amz-target": "Logs_20140328.PutLogEvents", "host": "logs.us-east-1.amazonaws.com", "x-amz-content-sha256": "7dbe84657fbd1885f46b4d0d51a6b49be58c78db693af0fe85e335f28f6efefd", "content-type": "application/x-amz-json-1.1"}


Request payload = {"logGroupName":"esp32-test","logEvents":[{"message":"This is a sample log message from esp32","timestamp":1700937032000}],"logStreamName":"esp32-test-stream-3"}

RESPONSE++++++++++++++++++++++++++++++++++++
Response code: 400

{'_content_consumed': False, 'raw': <SSLSocket>, 'encoding': 'utf-8', 'reason': b'Bad Request', '_cached': None, 'status_code': 400}
{"__type":"InvalidSignatureException","message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."}
>>> 

已尝试的解决措施

  • 确认系统时间正确
  • 验证所有哈希方法正确,并与在线工具对比
  • 严格遵循AWS官方签名生成步骤

内容的提问来源于stack exchange,提问作者Haisam Sharrouf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 11:50:54