2017-02-14 2 views
2

Я надоело видеть этот ответ:AWS S3 прямые возвращается загружать недействительная подпись (версия 4 подпись)

Запрос подписи мы рассчитали не совпадает с подписью вы предоставили. Проверьте свой ключ и метод подписи.

Я знаю версию этот вопрос был дан ответ здесь:

SO - AWS S3 browser upload using HTTP POST gives invalid signature

И я следовал каждую деталь этого не повезло, и я, вероятно, отсутствует что-то простое. Я использую 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> 

У меня есть ver маньяков, что результат Пример политики в этом примере:

AWS - Examples: Browser-Based Upload using HTTP POST (Using AWS Signature Version 4)

, а также в результате подпись соответствует примеру, используя предоставленные параметры и ключи. Но когда я пытаюсь выполнить POST на S3, я всегда получаю этот страшный ответ.

+0

Я думаю, что нашел Уолдо. В этом примере из вашего документа политики отсутствует '{" bucket ":" sigv4examplebucket "},' отсутствует. –

+0

@ Michael-sqlbot Я попробовал это с «ведром» в политике, а на самом деле все варианты политики, включенные в этот пример. Согласно этому http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html, единственными элементами в требуемой политике являются: x-amz-algorithm, x-amz-credential и x-amz-date. Основываясь на методе расчета подписи (который я получил отсюда: http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-dotnet), содержание политики не имеет значения для расчета подписи. – gsxrboy73

+0

Что ?! Noooooo. Это алгоритм для создания * подписи ключа * - не подписи. Вы используете ключ подписи для создания подписи * * представления base64 в политике. Один байт в политике сильно меняет подпись. Подпись защищает политику от несанкционированного доступа, а затем политика определяет, является ли запрос действительным, поскольку форма соответствует политике. –

ответ

2

Проблема заключалась в том, что дата, переданная методу GetSignatureKey, была неправильно отформатирована. Должно было быть только «20170214», а поле скрытой формы x-amz-date - это формат ISO8601 «20170214T000000Z». Я передавал то же значение в метод GetSignatureKey.

+0

Привет, Я пытаюсь использовать тот же код, что и вы, и я изменил дату, как вы упомянули в ответе. Тем не менее, я получаю ту же ошибку. @ gsxrboy73 У вас есть идеи? также я отправляю свой вопрос здесь: https: //stackoverflow.com/questions/49184746/aws-s3-direct-upload-returns-invalid-signature-version-4-signature-c-sharp – ali

Смежные вопросы