0

我在使用该UNSIGNED-PAYLOAD选项运行 POST 到 AWS kinesis 时遇到一些问题。

我主要使用此博客中的代码。

为了简单起见,我只签署了这两个标头:SignedHeaders=host;x-amz-date

需要提及的是,签署正文时一切正常(Kinesis 接受此作为有效签名):

signer.computeSignature(Collections.emptyMap(), Collections.emptyMap(), COMPUTED_HASH, "***", "***");

但是,如果我尝试切换到未签名的有效负载,我最终会得到InvalidSignatureException

signer.computeSignature(Collections.emptyMap(), Collections.emptyMap(), "UNSIGNED-PAYLOAD", "***", "***");

我打给 AWS 的电话是:

curl --location --request POST 'https://kinesis.us-east-1.amazonaws.com' \
--header 'host: kinesis.us-east-1.amazonaws.com' \
--header 'content-type: application/x-amz-json-1.1' \
--header 'x-amz-date: 20210810T123805Z' \
--header 'X-Amz-Target: Kinesis_20131202.PutRecord' \
--header '<whatever_compute_signature_returns>' \
--header 'X-Amz-Content-Sha256: UNSIGNED-PAYLOAD' \
--data-raw '{
  "StreamName": "my_stream",
  "Data": "c29tZV90ZXh0", # "some_text" hashed
  "PartitionKey": "partitionKey"
}'

所以我在工作版本和非工作版本之间唯一改变的是内容哈希(从我的内容的实际 sha256 到文字“UNSIGNED_PAYLOAD”)。

构建规范请求时正在使用哈希。对于非正文签名版本,这是错误的方法吗?

    protected static String getCanonicalRequest(URL endpoint,  

                                     String httpMethod, 

                                     String queryParameters,  

                                     String canonicalizedHeaderNames, 

                                     String canonicalizedHeaders,  

                                     String bodyHash) { 

    String canonicalRequest = 

                    httpMethod + "\n" + 

                    getCanonicalizedResourcePath(endpoint) + "\n" + 

                    queryParameters + "\n" + 

                    canonicalizedHeaders + "\n" + 

                    canonicalizedHeaderNames + "\n" + 

                    bodyHash; 

    return canonicalRequest; 

}

更新 我还尝试使用来自 aws-sdk-core 的签名者:

Request<Void> request = new DefaultRequest<Void>("kinesis"); 
request.setHttpMethod(HttpMethodName.POST);
request.setEndpoint(URI.create("https://kinesis.us-east-1.amazonaws.com"));

AWS4UnsignedPayloadSigner signerAws = new AWS4UnsignedPayloadSigner();
signerAws.setRegionName("us-east-1");
signerAws.setServiceName(request.getServiceName());
signerAws.sign(request, new AWSCredentials() {
  @Override
  public String getAWSAccessKeyId() {
    return "***";
  }

  @Override
  public String getAWSSecretKey() {
    return "***";
  }
});

使用上面生成的标题,我仍然得到相同的InvalidSignatureException.

这是否意味着 Kinesis PutRecord 不接受未签名的有效负载?

4

0 回答 0