1

So my iPhone app successfully uploads photos to Amazon S3. I used the same code as the S3Uploader example project with the latest (ver 1.6.0) Amazon AWS SDK for iOS. The problem is intermittently I'll get the SignatureDoesNotMatch error (The request signature we calculated does not match the signature you provided. Check your key and signing method.). There's no pattern to it. Currently my app is working around this error by doing a certain amount of retries on the delegate call didFailWithError:.

So far with my tests, there are enough retries so the user will not notice the error, but it is quite frustrating to know that I am getting a signature key error when my signature is clearly correct since it works at times. I am not sure if it is a url encoding error (my signature key has a + sign in it), but since I'm using the iOS SDK I don't see how the PUT url's are handled.

Also, I verified that my bucket name is all lower case, and my filenames are just numbers and a few alphabet letters. I also tried different regions and they all have the same result. In short it can take anywhere from 0 retries to 5 retries for to get a successful PUT without the SignatureDoesNotMatch error. Has anyone had a similar issue? Any help would be greatly appreciated. Thanks for reading.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
rymagno
  • 458
  • 2
  • 9
  • I'm one of the maintainers of the AWS SDK for iOS. You indicate that you're using the same code as the S3Uploader. Does this mean you are using embedded credentials? Note, we do not recommend this as you app could be compromised and credentials extracted. That being said, does this error occur only on end users' devices or have you been able to reproduce it on your own device or simulator? – Bob Kinney Jul 23 '13 at 16:35
  • Hi, Bob. Thanks for the reply! Also, thanks for the info on embedded credentials. Would IAM be the safer route? If so, could you direct me to some examples using IAM with the iOS SDK? In regards to my initial question, the app is still in development so I have only been able to test and produce it myself (in simulator - have not tried it on the device yet). So the only PUT requests have been from myself, thus far. Thanks for your time. – rymagno Jul 24 '13 at 00:25
  • Using IAM credentials would definitely be better than using the root credentials, but doesn't remove the issue of your application possibly being compromised. We recommend the use of either a TVM or web identity federation. Version 1.6.0 of the AWS SDK for iOS includes samples for both of these methods of credentials management. You can also read the following articles for more information [web identity federation](http://aws.amazon.com/articles/4617974389850313), [token vending machine](http://aws.amazon.com/articles/4611615499399490). – Bob Kinney Jul 24 '13 at 16:08
  • 1
    Thanks, Bob. Although my issue had nothing to do with any of this, I still benefited from your feedback. Instead of using IAM/embedded credentials I got the TVM server running on Elastic Beanstalk. Always good to learn new things. – rymagno Jul 26 '13 at 18:38

2 Answers2

3

You may need to massage the signature after you generate it, because valid base64 is not always valid in a query string. I must have run into the same problem problem once upon a time because I found the following comments in some code I wrote:

# the "+" is not url-safe, as it gets converted to a space somewhere along the line

# '+' => '%2B'

# while we're at it, we'll go ahead and convert the other non-safe-ish 
# characters even though the links seem to work without this step

# '/' => '%2F'
# '=' => '%3D'

My code does string search and replace for those 3 characters, changing them to their url-encoded equivalents before returning the query string to the caller. I used the search/replace tactic because the environment I was working in I didn't have a proper url-encoding library available. Since these are the only 3 base64 characters my code could generate that were not obviously url-safe, I apparently went ahead and handled all three possibilities.

Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427
  • Thanks Michael - Since I was using the AWS iOS SDK it was actually handling the URLs for me. But I will use this for reference if, in the future, I handle them myself. – rymagno Jul 26 '13 at 18:56
  • 1
    Mate, thanks so much for this. You saved me what I can only imagine would have been hours trying to work out what the hell was going on. Cheers mate. – Aaron Chambers Jun 25 '15 at 09:20
2

OK. So after spending the last couple days trying new buckets...trying all different NSString encoding/UIImage to NSData statements...switching from embedded to TVM...hopping back and forth from my project to the TVM demo...and reading pages and pages of debugging output...I found out it has nothing to do with any of those! :P

Once I realized I had inadvertently copied the AWS frameworks into my project folder, I removed them and re-added them without the copy box checked (referencing to my SDK's folder). Boom - no more signature errors.

The AWS SDK apparently doesn't like have multiple instances of its frameworks on one system. Hope this helps others! :)

rymagno
  • 458
  • 2
  • 9