Why AWS does not trust to pre-signed URLs generated by its own SDK
<p>I'm composing pre-signed URL for downloading objects from AWS S3. I use generatePresignedUrl method from AWS Java SDK. However, I get SignatureDoesNotMatch from AWS when making GET request using the generated pre-signed URL. I'm confused cause I use a method from the official SDK to generate it and a very simple GET request, but no luck. Any help much appreciated!</p>

<p>The code (taken from <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLJavaSDK.html" rel="nofollow">AWS docs</a>):</p>

<pre><code>java.util.Date expiration = new java.util.Date();
long milliSeconds = expiration.getTime();
milliSeconds += 1000 * 60 * 60; // Add 1 hour.
expiration.setTime(milliSeconds);

GeneratePresignedUrlRequest generatePresignedUrlRequest = 
new GeneratePresignedUrlRequest(bucketName, objectKey);
generatePresignedUrlRequest.setMethod(HttpMethod.GET); 
generatePresignedUrlRequest.setExpiration(expiration);

URL url = s3client.generatePresignedUrl(generatePresignedUrlRequest); 
</code></pre>

<p>Credentials which I use for connecting to AWS S3 are tested; I was able to download S3 objects using same credentials and S3 download method from AWS SDK. But the response I get from AWS to the composed URL (for example, <a href="https://ozland.s3.amazonaws.com/1865b563cdc94fa28ef41ee0b9b0e608?AWSAccessKeyId=...AWSAccessKeyId...&amp;Expires=1471300223&amp;Signature=pbgcRB0Zg%2B3iicDQQbVX%2FqdNAAc%3D" rel="nofollow">https://ozland.s3.amazonaws.com/1865b563cdc94fa28ef41ee0b9b0e608?AWSAccessKeyId=...AWSAccessKeyId...&amp;Expires=1471300223&amp;Signature=pbgcRB0Zg%2B3iicDQQbVX%2FqdNAAc%3D</a>) from above is:</p>

<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;Error&gt;&lt;Code&gt;SignatureDoesNotMatch&lt;/Code&gt;&lt;Message&gt;The request signature we calculated does not match the signature you provided. Check your key and signing method.&lt;/Message
&lt;AWSAccessKeyId&gt;...AWSAccessKeyId...&lt;/AWSAccessKeyId&gt;
&lt;StringToSign&gt;GET


1471300223
/ozland/1865b563cdc94fa28ef41ee0b9b0e608&lt;/StringToSign&gt;
&lt;SignatureProvided&gt;pbgcRB0Zg+3iicDQQbVX/qdNAAc=&lt;/SignatureProvided&gt;
&lt;StringToSignBytes&gt;47 45 54 0a 0a 0a 31 34 37 31 33 30 30 32 32 33 0a 2f 61 6c 61 62 61 6d 61 63 6f 75 6e 74 79 2f 31 38 36 35 62 35 36 33 63 64 65 39 34 66 61 32 38 65 66 34 31 65 65 30 63 39 62 30 65 36 30 38&lt;/StringToSignBytes&gt;
&lt;RequestId&gt;...RequestId...&lt;/RequestId&gt;
&lt;HostId&gt;...HostId...&lt;/HostId&gt;&lt;/Error&gt;
</code></pre>

<p><strong>The question is why response.StringToSign from above differs from the way AWS docs</strong> (<a href="http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html" rel="nofollow">AWS docs</a>) <strong>describe it.</strong> In particular, according to the docs, I expect StringToSign to be like:</p>

<pre><code>AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/iam/aws4_request
f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59
</code></pre>

<p><a href="https://github.com/gdbtek/aws-tools" rel="nofollow">aws-tools</a> works just fine for me for generating pre-signed URLs using exact same S3 bucket and credentials. But why am I getting SignatureDoesNotMatch here anyway?</p>

<p>Thank you!</p>