对于单平台集成,我需要创建一个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='

10-08 05:57