6

Ok, this is driving me nuts.

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.

My keys are correct and have been tested - no trailing whitespace etc.

The issue seems to be with the signature, it keeps getting the 'the request signature we calculated does not match the signature you provided. Check your key and signing method' 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.

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.

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

I am however following Amazon's documentation around authentication and to my simple mind, everything is being done correctly.

Here's how I'm generating the 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 go about working with it to attempt to perform 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 would be greatly appreciated.

S

4

3 回答 3

8

即使您不能直接使用适用于 iOS 的 AWS 开发工具包,它也是开源的,您可能会通过检查此处的请求签名代码获得一些想法:

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

于 2013-09-30T16:06:56.543 回答
1

当请求中缺少相应的标头时,您需要确保在该字符串中包含空值(例如Content-MD5,对于 PUT 请求是可选的,对于 GET 请求无意义 - 如果您的请求,您应该只在您正在签名的字符串中包含它的值在对 S3 的 API 调用中包含该标头)。

于 2013-09-30T18:43:23.470 回答
1

目前我正在开发基于 AFNetworking 1.0 的 S3 客户端框架(由于与旧操作系统兼容)。框架本身仍在开发中,但 AWS4-HMAC-SHA256 的所有请求签名方法都已实现并正在运行。您可以在 github 上找到该框架:https ://github.com/StudioIstanbul/SIAFAWSClient

随意分叉并实现您的功能,以便我们可以一起工作。目前所有基本的 S3 请求都已实现。

当然,您也可以将我的-(NSString*)AuthorizationHeaderStringForRequest:(NSMutableURLRequest*)request函数复制到您自己的代码中。AWS 关于这方面的文档目前不是很好,因为它缺少创建签名密钥的一些步骤。

于 2015-09-05T10:20:18.187 回答