title: AWS Authentication with Objective-C/Cocoa
body: <p>Ok, this is driving me nuts.</p>
  
  <p>I'm trying to create a simple AWS S3 client that would allow for basic interaction with S3, but it seems I'm doing something wrong and can't figure out what it is. It might be blatently obvious, but I'm not seeing it. </p>
  
  <p>My keys are correct and have been tested - no trailing whitespace etc. </p>
  
  <p>The issue seems to be with the signature, it keeps getting the '<strong>the request signature we calculated does not match the signature you provided. Check your key and signing method</strong>' error from Amazon's REST API. I've create various categories that add the base64, HMAC SHA1 generation functionality and I've also looked through various online examples, but no success so far. </p>
  
  <p>The reason for not using the library provided by Amazon is because it's aimed at Cocoa Touch and I don't want to hack around to make it work on Cocoa. </p>
  
  <p>You can grab a copy of all the files/code here: <a href="https://www.dropbox.com/s/8ts9q71dz3uopxp/S3Lite.zip" rel="noreferrer">https://www.dropbox.com/s/8ts9q71dz3uopxp/S3Lite.zip</a></p>
  
  <p>I am however following Amazon's documentation around authentication and to my simple mind, everything is being done correctly. </p>
  
  <p>Here's how I'm generating the signature:</p>
  
  <pre><code>-(NSString *)signRequest:(NSURLRequest *)request {
      NSMutableString *sig = [[NSMutableString alloc] init];
  
      // Request Method
      [sig appendFormat:@"%@\n", [request HTTPMethod]];
  
      // Content MD5
      [sig appendFormat:@"%@\n", [[request HTTPBody] MD5String]];
  
      // Content Type
      [sig appendFormat:@"%@\n", [request valueForHTTPHeaderField:@"Content-Type"]];
  
      // Date
      [sig appendFormat:@"%@\n", [request valueForHTTPHeaderField:@"Date"]];
  
      // Canonicalized Headers
      [sig appendFormat:@"%@\n", @""]; // Empty for now
  
      // Canonicalized Resource
      [sig appendFormat:@"%@", [NSString stringWithFormat:@"/%@%@", _bucket, request.URL.path]];
  
      NSString *encodedString = [[[sig dataUsingEncoding:NSUTF8StringEncoding]    hmacSHA1SignatureWithKey:_secretKey] base64String];
  
      return [[NSString alloc] initWithFormat:@"AWS %@:%@", _accessKey, encodedString];
  }
  </code></pre>
  
  <p>Here's how you go about working with it to attempt to perform a simple PUT request. </p>
  
  <pre><code>#import "S3Lite.h"
  
  S3Lite *aws =  [[S3Lite alloc] initWithAccessKey:@"&lt;access key&gt;"
                                     secretKey:@"&lt;secret key&gt;"
                                    bucketName:@"&lt;bucket name&gt;"
                                        region:kAmazonS3EUWest1Region
                                        useSSL:NO];
  
  NSData *file = [[NSData alloc] initWithContentsOfFile:@"&lt;path to a file&gt;"];
  
  [aws putObjectWithData:file inPath:@"aRandomFile.png" withContentType:nil];
  </code></pre>
  
  <p>Any help in the right direction would be greatly appreciated.</p>
  
  <p>S</p>