Here is an example as Objective-C methods. Note the separation of tasks into individual methods, each can be easily written & tested individually.
- (NSString *)signatureBase64 {
NSString *uri_path = [NSString stringWithFormat:@"%@?client=%@",@"/locations/haru-7",@"clientID"];
NSData *signature = [uri_path dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"signature Data: %@", signature);
NSString *signingKeyBase64 = @"c2lnbmluZ0tleQ==";
NSData *signingKey = [self decodeURLBase64String:signingKeyBase64];
NSLog(@"signingKey Data: %@", signingKey);
NSLog(@"signingKeyAscii: '%@'", [[NSString alloc] initWithData:signingKey encoding:NSUTF8StringEncoding]);
NSData *digest = [self hmacSha1:signature key:signingKey];
NSLog(@"digest Data: %@", digest);
NSString *signatureBase64 = [self encodeURLBase64Data:digest];
NSLog(@"signatureBase64: '%@'", signatureBase64);
return signatureBase64;
}
- (NSData *)decodeURLBase64String:(NSString *)string {
string = [string stringByReplacingOccurrencesOfString:@"-" withString:@"+"];
string = [string stringByReplacingOccurrencesOfString:@"_" withString:@"/"];
NSData *data = [[NSData alloc] initWithBase64Encoding:string];
return data;
}
- (NSString *)encodeURLBase64Data:(NSData *)data {
NSString *signatureBase64 = [data base64EncodedStringWithOptions:0];
signatureBase64 = [signatureBase64 stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
signatureBase64 = [signatureBase64 stringByReplacingOccurrencesOfString:@"?" withString:@"_"];
return signatureBase64;
}
// Note there is no intermediate buffer, this is a simple pattern.
- (NSData *)hmacSha1:(NSData *)data key:(NSData *)key {
NSMutableData *hmac = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH];
CCHmac( kCCHmacAlgSHA1,
key.bytes, key.length,
data.bytes, data.length,
hmac.mutableBytes);
return hmac;
}
NSLog output:
signatureData: <2f6c6f63 6174696f 6e732f68 6172752d 373f636c 69656e74 3d636c69 656e7449 44>
signingKeyBase64: 'c2lnbmluZ0tleQ=='
signingKey Data: <7369676e 696e674b 6579>
signingKeyAscii: 'signingKey'
digest Data: <8e4b88b6 111e3151 3b5d35d0 04e60cf9 8a984fb3>
signatureBase64: 'jkuIthEeMVE7XTXQBOYM-YqYT7M='