Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.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
C# AWS签名v4键值存储KVS在C中#_C#_Amazon Web Services_Amazon S3_Aws Sdk_Amazon Product Api - Fatal编程技术网

C# AWS签名v4键值存储KVS在C中#

C# AWS签名v4键值存储KVS在C中#,c#,amazon-web-services,amazon-s3,aws-sdk,amazon-product-api,C#,Amazon Web Services,Amazon S3,Aws Sdk,Amazon Product Api,我试图在C#中集成“签名AWS请求与签名版本4”。不幸的是,Amazon并没有详细介绍C#的实现。我已经在实施中试过运气了。但是它抛出了这个错误信息 “远程服务器返回错误:(403)禁止 注意:我在《邮递员》上做了这项工作,但无法在C#中工作。 接收错误:Message=“远程服务器返回错误:(403)禁止。 我已使用此文档进行签名 publicwebrequest-RequestPost(字符串canonicalUri、字符串canonicalquerystring、字符串jsonString

我试图在C#中集成“签名AWS请求与签名版本4”。不幸的是,Amazon并没有详细介绍C#的实现。我已经在实施中试过运气了。但是它抛出了这个错误信息

“远程服务器返回错误:(403)禁止

注意:我在《邮递员》上做了这项工作,但无法在C#中工作。 接收错误:Message=“远程服务器返回错误:(403)禁止。

我已使用此文档进行签名

publicwebrequest-RequestPost(字符串canonicalUri、字符串canonicalquerystring、字符串jsonString)
{
string hashedRequestPayload=CreateRequestPayload(jsonString);
字符串授权=符号(hashedRequestPayload,“PUT”、canonicalUri、CanonicalQueryString);
string requestDate=DateTime.ParseExact(DateTime.UtcNow.ToString(),“yyyyymmdd'T'HHMMSS'Z',CultureInfo.InvariantCulture).ToString();
WebRequest WebRequest=WebRequest.Create(canonicalUri+canonicalquerystring);
webRequest.Method=“PUT”;
webRequest.ContentType=ContentType;
webRequest.Headers.Add(“X-Amz-date”,requestDate);
webRequest.Headers.Add(“授权”,Authorization);
webRequest.Headers.Add(“x-amz-content-sha256”,hashedRequestPayload);
webRequest.ContentLength=jsonString.Length;
ascienceoding encoding=新的ascienceoding();
byte[]data=encoding.GetBytes(jsonString);
Stream newStream=webRequest.GetRequestStream();
newStream.Write(数据,0,数据长度);
使用(WebResponse=webRequest.GetResponse())
{
StreamReader responseReader=新的StreamReader(response.GetResponseStream());
var responseJson=responseReader.ReadToEnd();
}
返回webRequest;
}
常量字符串RegionName=“eu-west-1”//这是地区名称
常量字符串ServiceName=“执行api”;
常量字符串算法=“AWS4-HMAC-SHA256”;
const string ContentType=“应用程序/json”;
常量字符串主机=”;
const string SignedHeaders=“内容类型;主机;x-amz-content-sha256;x-amz-date”;
私有静态字符串CreateRequestPayload(字符串jsonString)
{
//这里应该是我们随POST请求发送的模型的JSON对象
//var jsonToSerialize=new{Data=String.Empty};
//如果发出GET请求,则将空字符串解析到序列化程序
//string requestPayload=new JavaScriptSerializer().Serialize(jsonToSerialize);
string hashedRequestPayload=HexEncode(Hash(ToBytes(jsonString));
返回hashedRequestPayload;
}
私有静态字符串符号(字符串hashedRequestPayload、字符串requestMethod、字符串canonicalUri、字符串canonicalQueryString)
{
var currentDateTime=DateTime.UtcNow;
var accessKey=“”;
var secretKey=“”;
var dateStamp=currentDateTime.ToString(“yyyyMMdd”);
//var requestDate=currentDateTime.ToString(“yyyyymmdd'T'HHMMSS'Z”);
var requestDate=DateTime.ParseExact(currentDateTime.ToString(),“yyyyymmdd'T'HHMMSS'Z',CultureInfo.InvariantCulture);
var credentialScope=string.Format(“{0}/{1}/{2}/aws4_请求”,日期戳,区域名称,服务名称);
var headers=新的SortedDictionary{
{“内容类型”,内容类型},
{“主机”,主机},
{“x-amz-date”,requestDate.ToString()}
};
string canonicalHeaders=string.Join(“\n”,headers.Select(x=>x.Key.ToLowerInvariant()+”:“+x.Value.Trim())+”\n”;
//任务1:为签名版本4创建规范请求
字符串canonicalRequest=requestMethod+“\n”+canonicalUri+“\n”+canonicalQueryString+“\n”+canonicalHeaders+“\n”+SignedHeaders+“\n”+hashedRequestPayload;
字符串hashedCanonicalRequest=HexEncode(Hash(ToBytes(canonicalRequest));
//任务2:为签名版本4创建要签名的字符串
字符串stringToSign=Algorithm+“\n”+requestDate+“\n”+credentialScope+“\n”+hashedCanonicalRequest;
//任务3:计算AWS签名版本4
字节[]signingKey=GetSignatureKey(secretKey、dateStamp、RegionName、ServiceName);
字符串签名=HexEncode(HmacSha256(stringToSign,signingKey));
//任务4:准备已签名的请求
//授权:算法凭据=访问密钥ID/凭据范围,SignedHeadaers=SignedHeaders,Signature=签名
string authorization=string.Format(“{0}凭证={1}/{2}/{3}/{4}/aws4_请求,SignedHeaders={5},Signature={6}”,
算法、accessKey、日期戳、RegionName、ServiceName、SignedHeader、签名);
退货授权;
}
私有静态字节[]GetSignatureKey(字符串键、字符串日期戳、字符串regionName、字符串serviceName)
{
字节[]kDate=HmacSha256(日期戳,以字节为单位(“AWS4”+键));
字节[]kRegion=HmacSha256(区域名称,kDate);
字节[]kService=HmacSha256(serviceName,kRegion);
返回HmacSha256(“aws4_请求”,k服务);
}
专用静态字节[]ToBytes(字符串str)
{
返回Encoding.UTF8.GetBytes(str.tocharray());
}
专用静态字符串HexEncode(字节[]字节)
{
返回BitConverter.ToString(字节)。替换(“-”,string.Empty)。ToLowerInvariant();
}
专用静态字节[]哈希(字节[]字节)
{
返回SHA256.Create().ComputeHash(字节);
}
专用静态字节[]HmacSha256(字符串数据,字节[]键)
{
返回新的HMACSHA256(键).ComputeHash(ToBytes(数据));
}

您是否愿意使用
HttpClient
而不是
WebRequest
?在这种情况下,我创建了一个名为的NuGet包,该包已被验证可与AWS API网关一起使用。

基本上,我需要在amazon web serv中存储一个密钥值
    public WebRequest RequestPost(string canonicalUri, string canonicalQueriString, string jsonString)
    {
        string hashedRequestPayload = CreateRequestPayload(jsonString);

        string authorization = Sign(hashedRequestPayload, "PUT", canonicalUri, canonicalQueriString);
        string requestDate = DateTime.ParseExact(DateTime.UtcNow.ToString(), "YYYYMMDD'T'HHMMSS'Z'", CultureInfo.InvariantCulture).ToString();

        WebRequest webRequest = WebRequest.Create(canonicalUri + canonicalQueriString);

        webRequest.Method = "PUT";
        webRequest.ContentType = ContentType;
        webRequest.Headers.Add("X-Amz-date", requestDate);
        webRequest.Headers.Add("Authorization", authorization);
        webRequest.Headers.Add("x-amz-content-sha256", hashedRequestPayload);
        webRequest.ContentLength = jsonString.Length;

        ASCIIEncoding encoding = new ASCIIEncoding();
        byte[] data = encoding.GetBytes(jsonString);

        Stream newStream = webRequest.GetRequestStream();
        newStream.Write(data, 0, data.Length);
        using (WebResponse response = webRequest.GetResponse())
        {
            StreamReader responseReader = new StreamReader(response.GetResponseStream());
            var responseJson = responseReader.ReadToEnd();
        }

        return webRequest;
    }

    const string RegionName = "eu-west-1"; //This is the regionName
    const string ServiceName = "execute-api";
    const string Algorithm = "AWS4-HMAC-SHA256";
    const string ContentType = "application/json";
    const string Host = "<hostname>";
    const string SignedHeaders = "content-type;host;x-amz-content-sha256;x-amz-date";

    private static string CreateRequestPayload(string jsonString)
    {
        //Here should be JSON object of the model we are sending with POST request
        //var jsonToSerialize = new { Data = String.Empty };

        //We parse empty string to the serializer if we are makeing GET request
        //string requestPayload = new JavaScriptSerializer().Serialize(jsonToSerialize);
        string hashedRequestPayload = HexEncode(Hash(ToBytes(jsonString)));

        return hashedRequestPayload;
    }

    private static string Sign(string hashedRequestPayload, string requestMethod, string canonicalUri, string canonicalQueryString)
    {
        var currentDateTime = DateTime.UtcNow;
        var accessKey = "";
        var secretKey = "";

        var dateStamp = currentDateTime.ToString("yyyyMMdd");
        //var requestDate = currentDateTime.ToString("YYYYMMDD'T'HHMMSS'Z");
        var requestDate = DateTime.ParseExact(currentDateTime.ToString(), "YYYYMMDD'T'HHMMSS'Z'", CultureInfo.InvariantCulture);
        var credentialScope = string.Format("{0}/{1}/{2}/aws4_request", dateStamp, RegionName, ServiceName);

        var headers = new SortedDictionary<string, string> {
        { "content-type", ContentType },
        { "host", Host  },
        { "x-amz-date", requestDate.ToString() }
    };

        string canonicalHeaders = string.Join("\n", headers.Select(x => x.Key.ToLowerInvariant() + ":" + x.Value.Trim())) + "\n";

        // Task 1: Create a Canonical Request For Signature Version 4
        string canonicalRequest = requestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + SignedHeaders + "\n" + hashedRequestPayload;
        string hashedCanonicalRequest = HexEncode(Hash(ToBytes(canonicalRequest)));

        // Task 2: Create a String to Sign for Signature Version 4
        string stringToSign = Algorithm + "\n" + requestDate + "\n" + credentialScope + "\n" + hashedCanonicalRequest;

        // Task 3: Calculate the AWS Signature Version 4
        byte[] signingKey = GetSignatureKey(secretKey, dateStamp, RegionName, ServiceName);
        string signature = HexEncode(HmacSha256(stringToSign, signingKey));

        // Task 4: Prepare a signed request
        // Authorization: algorithm Credential=access key ID/credential scope, SignedHeadaers=SignedHeaders, Signature=signature

        string authorization = string.Format("{0} Credential={1}/{2}/{3}/{4}/aws4_request, SignedHeaders={5}, Signature={6}",
        Algorithm, accessKey, dateStamp, RegionName, ServiceName, SignedHeaders, signature);

        return authorization;
    }

    private static byte[] GetSignatureKey(string key, string dateStamp, string regionName, string serviceName)
    {
        byte[] kDate = HmacSha256(dateStamp, ToBytes("AWS4" + key));
        byte[] kRegion = HmacSha256(regionName, kDate);
        byte[] kService = HmacSha256(serviceName, kRegion);
        return HmacSha256("aws4_request", kService);
    }

    private static byte[] ToBytes(string str)
    {
        return Encoding.UTF8.GetBytes(str.ToCharArray());
    }

    private static string HexEncode(byte[] bytes)
    {
        return BitConverter.ToString(bytes).Replace("-", string.Empty).ToLowerInvariant();
    }

    private static byte[] Hash(byte[] bytes)
    {
        return SHA256.Create().ComputeHash(bytes);
    }

    private static byte[] HmacSha256(string data, byte[] key)
    {
        return new HMACSHA256(key).ComputeHash(ToBytes(data));
    }