Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon API在C#.NET中生成请求签名_C#_Asp.net_Asp.net Mvc_Amazon Web Services_C# 4.0 - Fatal编程技术网

Amazon API在C#.NET中生成请求签名

Amazon API在C#.NET中生成请求签名,c#,asp.net,asp.net-mvc,amazon-web-services,c#-4.0,C#,Asp.net,Asp.net Mvc,Amazon Web Services,C# 4.0,我正在尝试找出如何在.NET应用程序中传递参数。URL请求如下所示: http://webservices.amazon.com/onca/xml? Service=AWSECommerceService &Operation=ItemLookup &ResponseGroup=Large &SearchIndex=All &IdType=UPC &ItemId=635753490879 &AWSAccessKeyId=

我正在尝试找出如何在.NET应用程序中传递参数。URL请求如下所示:

http://webservices.amazon.com/onca/xml?
  Service=AWSECommerceService
  &Operation=ItemLookup
  &ResponseGroup=Large
  &SearchIndex=All
  &IdType=UPC
  &ItemId=635753490879
  &AWSAccessKeyId=[Your_AWSAccessKeyID]
  &AssociateTag=[Your_AssociateTag]
  &Timestamp=[YYYY-MM-DDThh:mm:ssZ]
  &Signature=[Request_Signature]
我感到困惑的是:

 &Timestamp=[YYYY-MM-DDThh:mm:ssZ]
      &Signature=[Request_Signature]
我不确定是否可以简单地对时间戳部分执行类似的操作:

var TimeStamp  = DateTime.Now; // without any special datetime formating? 
所以我的问题是如何在请求URL中生成这个签名URL

我有上面所有的参数,但我不知道如何生成最后一个


有人能帮我吗?

AWS使用HMAC请求签名。一般来说,其工作方式是创建一条“消息”,它由访问密钥、请求头、请求体和时间戳等组成。然后HMAC将此“消息”发送给您,并将其作为您请求的“签名”。这可以防止重播攻击,因为每个请求必须具有唯一的签名

看起来时间戳只需采用ISO格式(
YYYY-MM-DDThh:MM:ssZ
),因此,不,您不能只使用
DateTime.Now
ToString
使用的默认格式将不是ISO。相反,您需要使用以下内容:

DateTime.Now.ToString("yyyy-MM-ddThh:mm:sszzz");
或者,实际上最好使用UTC时间并简单地附加一个
Z

DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ssZ");
关于创建签名,请参见,其中他们提供了一些示例代码:

static byte[] HmacSHA256(String data, byte[] key)
{
    String algorithm = "HmacSHA256";
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(algorithm);
    kha.Key = key;

    return kha.ComputeHash(Encoding.UTF8.GetBytes(data));
}

static byte[] getSignatureKey(String key, String dateStamp, String regionName, String serviceName)
{
    byte[] kSecret = Encoding.UTF8.GetBytes(("AWS4" + key).ToCharArray());
    byte[] kDate = HmacSHA256(dateStamp, kSecret);
    byte[] kRegion = HmacSHA256(regionName, kDate);
    byte[] kService = HmacSHA256(serviceName, kRegion);
    byte[] kSigning = HmacSHA256("aws4_request", kService);

    return kSigning;
}

AWS使用HMAC请求签名。一般来说,其工作方式是创建一条“消息”,它由访问密钥、请求头、请求体和时间戳等组成。然后HMAC将此“消息”发送给您,并将其作为您请求的“签名”。这可以防止重播攻击,因为每个请求必须具有唯一的签名

看起来时间戳只需采用ISO格式(
YYYY-MM-DDThh:MM:ssZ
),因此,不,您不能只使用
DateTime.Now
ToString
使用的默认格式将不是ISO。相反,您需要使用以下内容:

DateTime.Now.ToString("yyyy-MM-ddThh:mm:sszzz");
或者,实际上最好使用UTC时间并简单地附加一个
Z

DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ssZ");
关于创建签名,请参见,其中他们提供了一些示例代码:

static byte[] HmacSHA256(String data, byte[] key)
{
    String algorithm = "HmacSHA256";
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(algorithm);
    kha.Key = key;

    return kha.ComputeHash(Encoding.UTF8.GetBytes(data));
}

static byte[] getSignatureKey(String key, String dateStamp, String regionName, String serviceName)
{
    byte[] kSecret = Encoding.UTF8.GetBytes(("AWS4" + key).ToCharArray());
    byte[] kDate = HmacSHA256(dateStamp, kSecret);
    byte[] kRegion = HmacSHA256(regionName, kDate);
    byte[] kService = HmacSHA256(serviceName, kRegion);
    byte[] kSigning = HmacSHA256("aws4_request", kService);

    return kSigning;
}
与这里和其他地方找到的大多数答案相反,这是唯一可行的方法。必须对整个请求进行散列,而不仅仅是特定的参数。我无法与其他亚马逊服务交谈,但商业服务必须这样做

这里和其他地方的许多答案都提到了这一点: 这肯定是不对的。如果您没有传递区域参数,Amazon如何创建相同的签名,因为它没有所有的信息

与这里和其他地方找到的大多数答案相反,这是唯一可行的方法。必须对整个请求进行散列,而不仅仅是特定的参数。我无法与其他亚马逊服务交谈,但商业服务必须这样做

这里和其他地方的许多答案都提到了这一点:
这肯定是不对的。如果您没有传递区域参数,Amazon如何创建相同的签名,因为它没有所有的信息

有人吗??有什么建议吗?有人吗??有什么建议吗?克里斯哇,非常感谢!!!我找到了这段代码,但我仍然对参数的“RegionName”和“ServiceName”部分感到困惑,我需要在这部分放些什么??这是AWS特有的东西,但我相信它们指的是你们的地区,因为AWS之类的云服务通常是地区特有的(
east-us-1
)。不管你在演什么,你都会去那里。该服务很可能就是您请求的特定AWS服务(例如,
iam
),非常感谢!!传递到getSignatureMethod的日期戳如何,它是否需要以与时间戳相同的格式(yyyy-MM-ddThh:MM:ssZ)传递?是的。ISO日期对于任何类型的数据交换都是非常必要的。它之所以被称为ISO,是因为它是国际标准组织的标准格式,几乎是唯一可以普遍理解的日期格式。看起来AWS希望签名为十六进制摘要。在C#中,您可以通过
String.Concat(bytes.Select(b=>b.ToString(“X2”)).ToArray()来获得它。不确定这是否重要,但AWS示例签名都是小写的,因此您可能还需要调用
ToLower
。Chris wow非常感谢!!!我找到了这段代码,但我仍然对参数的“RegionName”和“ServiceName”部分感到困惑,我需要在这部分放些什么??这是AWS特有的东西,但我相信它们指的是你们的地区,因为AWS之类的云服务通常是地区特有的(
east-us-1
)。不管你在演什么,你都会去那里。该服务很可能就是您请求的特定AWS服务(例如,
iam
),非常感谢!!传递到getSignatureMethod的日期戳如何,它是否需要以与时间戳相同的格式(yyyy-MM-ddThh:MM:ssZ)传递?是的。ISO日期对于任何类型的数据交换都是非常必要的。它之所以被称为ISO,是因为它是国际标准组织的标准格式,几乎是唯一可以普遍理解的日期格式。看起来AWS希望签名为十六进制摘要。在C#中,您可以通过
String.Concat(bytes.Select(b=>b.ToString(“X2”)).ToArray()来获得它。不确定这是否重要,但AWS示例签名都是小写的,因此您可能还需要调用
ToLower