使用Objective-C / Cocoa进行AWS身份验证

时间:2013-09-25 15:49:49

标签: objective-c cocoa amazon-web-services amazon-s3

好的,这让我疯了。

我正在尝试创建一个简单的AWS S3客户端,允许与S3进行基本交互,但似乎我做错了什么并且无法弄清楚它是什么。它可能很明显,但我没有看到它。

我的密钥是正确的并且已经过测试 - 没有尾随空格等。

问题似乎与签名有关,它不断得到'我们计算的请求签名与您提供的签名不匹配。从Amazon的REST API检查您的密钥和签名方法'错误。我创建了各种类别,添加了base64,HMAC SHA1生成功能,我还查看了各种在线示例,但到目前为止还没有成功。

不使用亚马逊提供的库的原因是因为它针对的是Cocoa Touch,而且我不想破解它使它适用于Cocoa。

您可以在此处获取所有文件/代码的副本:https://www.dropbox.com/s/8ts9q71dz3uopxp/S3Lite.zip

然而,我正在关注亚马逊关于身份验证的文档,而且简单地说,一切都正确完成。

以下是我如何生成签名:

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

以下是您如何使用它来尝试执行简单的PUT请求。

#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];

非常感谢任何正确方向的帮助。

取值

3 个答案:

答案 0 :(得分:8)

即使您无法直接使用AWS SDK for iOS,它也是开源的,您可能会在此处检查请求签名代码中获得一些想法:

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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

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

相关问题