Showing posts with label amazon cloud Query hmac sha256 urlencode private key ec2. Show all posts
Showing posts with label amazon cloud Query hmac sha256 urlencode private key ec2. Show all posts

Monday, November 1, 2010

How to construct an Amazon Query based url

I am currently writing an iPhone app to manage Amazon Cloud infrastructure and thought it might be helpful to share some of the code with the community.
In this post i will include two methods, one to url encode a string and the second to construct a Query based url.

#import "AWSUtils.h"

#include <CommonCrypto/CommonHMAC.h>

#import "Base64Encoder.h"

@implementation AWSUtils

+(NSString*) calculateHMACWithKey:(NSString*) key andData:(NSString*) data{

const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];

const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];

unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];

CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

NSData *hmac = [[NSData alloc] initWithBytes:cHMAC

length:sizeof(cHMAC)];

return [Base64Encoder encode:hmac];

}

+(NSString*) urlEncode:(NSString*) url {

return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,

(CFStringRef)url,

NULL,

(CFStringRef)@"!*'();:@+$,/?%#[]",

kCFStringEncodingUTF8 );

}

+(NSString*) getQueryString:(NSMutableDictionary*) dict{

NSEnumerator *enumerator = [[[dict allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] objectEnumerator];

NSString *key;

NSString *queryString = [[[NSString alloc] init] autorelease];

NSMutableArray *queryArray = [[[NSMutableArray alloc] initWithCapacity:[dict count]] autorelease];

while (key = [enumerator nextObject]) {

[queryArray addObject:[NSString stringWithFormat:@"%@=%@",[AWSUtils urlEncode:key], [AWSUtils urlEncode:(NSString*)[dict valueForKey:key]]]];

}

queryString = [queryArray componentsJoinedByString:@"&"];

NSString *signedUrl = [AWSUtils calculateHMACWithKey:@"private key" andData:[NSString stringWithFormat:@"GET\nec2.amazonaws.com\n/\nAWSAccessKeyId=accessKeyId&%@",queryString]];

NSString *encodedAndSignedUrl = [AWSUtils urlEncode:signedUrl];

NSString *urlToUse = [NSString stringWithFormat:@"https://ec2.amazonaws.com/?%@&Signature=%@&AWSAccessKeyId=accesskeyId",queryString, encodedAndSignedUrl];

return urlToUse;

}

@end