AWS Authentication with Objective-C / Cocoa

Okay, this is driving me crazy.

I am trying to create a simple AWS S3 client that will allow basic interaction with S3, but it seems that I am doing something wrong and cannot understand what it is. This may be obvious, but I do not see it.

My keys are correct and have been tested - no spaces, etc.

The problem seems to be related to the signature, it continues to receive the requested signature, which we have calculated, does not match the signature that you provided. Check your key and signature method from the Amazon REST API. I create various categories that add the base64 generation functionality, HMAC SHA1, and I also looked at various online examples, but have not achieved anything so far.

The reason I don’t use the library provided by Amazon is because it targets Cocoa Touch and I don’t want to hack it so that it works on Cocoa.

You can get a copy of all files / code here: https://www.dropbox.com/s/8ts9q71dz3uopxp/S3Lite.zip

However, I follow the Amazon documentation on authentication and my simple mind, everything is done correctly.

This is how I create a signature:

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

Here's how you are going to work with it to try and execute a simple PUT request.

 #import "S3Lite.h" S3Lite *aws = [[S3Lite alloc] initWithAccessKey:@"<access key>" secretKey:@"<secret key>" bucketName:@"<bucket name>" region:kAmazonS3EUWest1Region useSSL:NO]; NSData *file = [[NSData alloc] initWithContentsOfFile:@"<path to a file>"]; [aws putObjectWithData:file inPath:@"aRandomFile.png" withContentType:nil]; 

Any help in the right direction is appreciated.

S

+6
source share
3 answers

Even if you cannot use the AWS SDK for iOS directly, it is open source, and you can get some ideas from studying the request signature code here:

https://github.com/aws/aws-sdk-ios/blob/master/AWSCore/Authentication/AWSSignature.m

+8
source

You need to include empty values ​​in this line when the corresponding header is absent in the request (for example, Content-MD5 is optional for PUT requests and meaningless for GET requests - you should include only its value in the line that you’re if your request includes this header in the API call on S3).

+1
source

I am currently developing an S3 client platform based on AFNetworking 1.0 (due to compatibility with older operating systems). The infrastructure itself is still under development, but all request signing methods for AWS4-HMAC-SHA256 are already implemented and working. You can find the structure on github: https://github.com/StudioIstanbul/SIAFAWSClient

Feel free to branch out and perform your functions so that we can work together. Currently, all major S3 requests are implemented.

Of course, you can just copy my request - (NSString *) AuthorizationHeaderStringForRequest: (NSMutableURLRequest *) to your own code. The AWS documentation on this subject is not very good so far, as some steps are not enough when creating signature keys.

+1
source

Source: https://habr.com/ru/post/954615/


All Articles