向Amazon Web服务REST API发出请求,无法使请求签名工作

时间:2016-09-08 21:55:17

标签: javascript amazon-web-services request hmac cryptojs

所以我试图向亚马逊的产品API发出请求,但我无法弄清楚如何让签名工作。我正在关注另一个堆栈溢出帖子,可以在这里找到:How can I create a signature for AWS in Javascript?,但仍然无法满足我的要求。以下是我发送的请求(目前通过邮递员进行测试)。

http://webservices.amazon.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[MY_ACCESSKEY]&Operation=ItemSearch&Keywords=the%20hunger%20games&SearchIndex=Books &Timestamp=2016-09-09T12:00:00Z&Signature=9RTSas234dfRTs3R%ErA8%

我制作了一个假签名,类似于我从这个函数得到的签名:

let service = "AWSECommerceService";
let timestamp = "2016-09-09T12:00:00Z";
let operation = "ItemSearch";
let secret = "MY_AMAZONSECRET";
let signature = CryptoJS.HmacSHA1(service + operation + timestamp, secret).toString(CryptoJS.enc.Base64);
console.log(signature);

记录到控制台的结果如下所示:9RTSas234dfRTs3R+ErA8=

从我在此阅读http://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html,我认为您需要更换' +'和' ='到'%'迹象。当我按原样保留+和=符号时,我从AWS得到以下响应:

<?xml version="1.0"?>
<ItemSearchErrorResponse xmlns="http://ecs.amazonaws.com/doc/2005-10-05/">
    <Error>
        <Code>SignatureDoesNotMatch</Code>
        <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.</Message>
    </Error>
    <RequestId>{MY_REQUESTID}</RequestId>
</ItemSearchErrorResponse>

但是当我将它们更改为%&#39; s时,我得到了这样的回复:

<?xml version="1.0"?>
<ItemSearchErrorResponse xmlns="http://ecs.amazonaws.com/doc/2005-10-05/">
    <Error>
        <Code>MissingParameter</Code>
        <Message>The request must contain the parameter Signature.</Message>
    </Error>
    <RequestId>{MY_REQUESTID}</RequestId>
</ItemSearchErrorResponse>

即使请求中存在Signature参数。关于如何解决这个问题的任何想法。我使用crypto-js来创建签名,可在此处找到:https://www.npmjs.com/package/crypto-js

1 个答案:

答案 0 :(得分:0)

  

我认为你需要更换&#39; +&#39;和&#39; =&#39;到&#39;%&#39;迹象。

是的,但您不能仅用%替换它们。使用此地图:

+ becomes %2B
/ becomes %2F
= becomes %3D

这称为url-encoding,url-escaping或percent-encoding。字符由文字%替换,后跟其2位十六进制ASCII等效字符。

9RTSas234dfRTs3R+ErA8= becomes 
9RTSas234dfRTs3R%2BErA8%3D