对于单平台集成,我需要创建一个Base64签名https://singleplatform.jira.com/wiki/display/PubDocs/SinglePlatform+Publisher+Integration#SinglePlatformPublisherIntegration-BuildingValidURLs
这是用于创建Base64签名的ruby脚本,现在我想在iOS中创建它,可以正常工作。
require 'hmac-sha1'
require 'base64'
def make_signature(uri_path, params, client_id, secret)
padding_factor = (4 - secret.length % 4) % 4
secret += "=" * padding_factor
secret = secret.gsub(/[-_]/, {"-" => "+", "_" => "/"})
binary_key = Base64.decode64(secret)
params.update({"client" => client_id})
path = uri_path + "?" + params.collect{|k,v| "#{k}=#{v}"}.inject{|initial,cur| initial + "&" + cur}
digest = HMAC::SHA1.new(binary_key).update(path).digest
digest = Base64.encode64(digest).gsub(/[+\/]/, {"+" => "-", "/" => "_"}).delete("=")
return "#{path}&sig=#{digest}"
end
puts 'http://api.singleplatform.co' + make_signature('/locations/haru-7', {}, "YOUR CLIENT ID", "YOUR SECRET")
我尝试过的
我试过https://github.com/MealCatcher/objc-singleplatform它不起作用。
我还尝试了Base64和iOS 7 CommonHMAC.h框架。
//To HMAC-SHA1 Signing
static NSData *HMAC_SHA1(NSString *data, NSString *key) {
unsigned char buf[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, [key UTF8String], [key length], [data UTF8String], [data length], buf);
return [NSData dataWithBytes:buf length:CC_SHA1_DIGEST_LENGTH];
}
//To Retrieve your private key For URL
NSString *uri_path = [NSString stringWithFormat:@"%@?client=%@",@"/locations/haru-7",@"clientID"];
NSMutableString *secret = [NSMutableString stringWithFormat:@"%@=",signingKey];
[secret stringByReplacingOccurrencesOfString:@"-" withString:@"+"];
[secret stringByReplacingOccurrencesOfString:@"_" withString:@"/"];
NSData *signature = HMAC_SHA1(uri_path, [secret base64DecodedString]);
NSString *base64Signature = [signature base64EncodedString];
[base64Signature stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
[base64Signature stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
提前致谢。
完整解决方案:
https://github.com/ronakjangir47/SinglePlatformSignature
最佳答案
这是Objective-C方法的示例。注意将任务分成单独的方法,每个方法都可以轻松地单独编写和测试。
- (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输出:
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='