簡體   English   中英

AWS S3直接上載返回無效簽名(版本4簽名)

[英]AWS S3 direct upload returns invalid signature (version 4 signature)

我厭倦了看到這個回應:

我們計算的請求簽名與您提供的簽名不匹配。 檢查您的密鑰和簽名方法。

我知道這個問題的版本已在這里得到解答:

SO - 使用HTTP POST上傳AWS S3瀏覽器會產生無效簽名

而且我沒有運氣地遵循它的每一個細節,我可能會錯過一些簡單的東西。 我正在使用C#生成策略和v4 Aws簽名。 這是政策代碼:

var policyBuilder = new StringBuilder();

policyBuilder.AppendFormat("{{ \"expiration\": \"{0}\",\r\n", "2017-12-30T12:00:00.000Z");
policyBuilder.Append("  \"conditions\": [\r\n");
policyBuilder.Append("    [\"starts-with\", \"$key\", \"\"],\r\n");
policyBuilder.AppendFormat("    {{\"x-amz-credential\": \"{1}\"}},\r\n",  <MyAccessKey>/20170214/us-east-2/s3/aws4_request));
policyBuilder.Append("    {\"x-amz-algorithm\": \"AWS4-HMAC-SHA256\"},\r\n");
policyBuilder.Append("    {\"x-amz-date\": \"20170214T000000Z\" }\r\n");
policyBuilder.Append("  ]\r\n}");

var policyString = policyBuilder.ToString();
var policyStringBytes = Encoding.UTF8.GetBytes(policyString);
return Convert.ToBase64String(policyStringBytes);

這是用於生成簽名的代碼:

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;
}

public static string ToHexString(byte[] data, bool lowercase)
{
    var sb = new StringBuilder();
    for (var i = 0; i < data.Length; i++)
    {
        sb.Append(data[i].ToString(lowercase ? "x2" : "X2"));
    }
    return sb.ToString();
}

將所有這些結合在一起的方法:

public string GetS3PolicySignatureV4(string policy)
{
    byte[] signingKey = GetSignatureKey(<MySecretKey>, "20170214T000000Z", "us-east-2", "s3");
    byte[] signature = HmacSHA256(policy, signingKey);
    return AWS4SignerBase.ToHexString(signature, true);
}

這是html表單:

<form action="http://<BucketName>.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
    <input type="hidden" name="key" value="<FileKey>" />
    <input type="hidden" name="x-amz-credential" value="<MyAccessKey>/20170214/us-east-2/s3/aws4_request"/>
    <input type="hidden" name="x-amz-algorithm" value="AWS4-HMAC-SHA256" />
    <input type="hidden" name="x-amz-date" value="20170214T000000Z" />
    <input type="hidden" name="policy" value='<Base64PolicyResult>' />
    <input type="hidden" name="x-amz-signature" value="<GenerateSignature>" />
    File:
    <input type="file" name="file" /> <br />
    <input type="submit" name="submit" value="Upload to Amazon S3" />
</form>

我已經驗證了此示例中的示例策略結果:

AWS - 示例:使用HTTP POST進行基於瀏覽器的上載(使用AWS簽名版本4)

以及使用提供的參數和鍵匹配示例的結果簽名。 但是當我嘗試POST到S3時,我總是得到那種可怕的反應。

問題是傳遞給GetSignatureKey方法的日期格式不正確。 本來應該是“20170214”,隱藏的表格字段x-amz-date是ISO8601格式的“20170214T000000Z”。 我將相同的值傳遞給GetSignatureKey方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM