ios - Objective-C 中 HMAC SHA1 实现的问题

标签 ios objective-c cocoa hmacsha1 commoncrypto

我正在尝试使用 HMAC-SHA1 算法为休息请求创建 base64 签名。我专门使用 SinglePlatform API,步骤是:

  1. 去掉请求的域部分,只留下路径和查询:/locations/haru-7?client=YOUR_CLIENT_ID
  2. 检索您的私钥,该私钥以经过修改的 Base64 编码用于 URL,并使用 HMAC-SHA1 算法对上述 URL 进行签名。您可能需要将签名 key 解码为其原始二进制格式。在许多加密库中,生成的签名将采用二进制格式。
  3. 使用针对 URL 的修改后的 Base64 对生成的二进制签名进行编码,以将此签名转换为可以在 URL 中传递的内容。 使用 sig 参数将此签名附加到 URL:

我目前的实现如下:

    // Convert a modified Base64 key into Base64
NSString *modifiedKey = [SIGNING_KEY stringByReplacingOccurrencesOfString:@"-" withString:@"+"];
modifiedKey = [modifiedKey stringByReplacingOccurrencesOfString:@"_" withString:@"/"];

// Decode the Base64 key
NSData *key = [NSData dataFromBase64String:modifiedKey];

// Construct a url with params
NSString *data = [NSString stringWithFormat:@"/locations/%@?client=%@", _id, CLIENT_ID];

// Convert key and data to c chars
const char *keyBytes = [key bytes];
const char *baseStringBytes = [data cStringUsingEncoding:NSUTF8StringEncoding];

unsigned char digestBytes[CC_SHA1_DIGEST_LENGTH];

CCHmacContext ctx;
CCHmacInit(&ctx, kCCHmacAlgSHA1, keyBytes, strlen(keyBytes));
CCHmacUpdate(&ctx, baseStringBytes, strlen(baseStringBytes));
CCHmacFinal(&ctx, digestBytes);

NSData *digestData = [NSData dataWithBytes:digestBytes length:CC_SHA1_DIGEST_LENGTH];

// Reconvert the into Base64 modified 
NSString *signingKey = [digestData base64EncodedString];
signingKey = [signingKey stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
signingKey = [signingKey stringByReplacingOccurrencesOfString:@"/" withString:@"_"];

if ( [data hasSuffix:@"="] ) {
    [signingKey substringToIndex:[hassigningKeyh length]-1];
}

NSLog(@"Signing Key: %@", signingKey);

我最初收到的签名 key 是经过修改的 Base64,这就是我替换 -+_/字符的原因。此实现已返回正确的签名 key ,但不一致。

我在将 Objective-C 转换为 C 时是否做错了什么?有更好的方法来处理这个问题吗?

我的应用程序正在使用 ARC。

最佳答案

问题是我用 C 方法来确定数据长度:

CCHmacContext ctx;
CCHmacInit(&ctx, kCCHmacAlgSHA1, keyBytes, strlen(keyBytes));
CCHmacUpdate(&ctx, baseStringBytes, strlen(baseStringBytes));
CCHmacFinal(&ctx, digestBytes);

当我使用 NSString/NSData 长度方法时,它一直有效:

CCHmacContext ctx;
CCHmacInit(&ctx, kCCHmacAlgSHA1, keyBytes, [key length]);
CCHmacUpdate(&ctx, baseStringBytes, [data length]);
CCHmacFinal(&ctx, digestBytes);

编辑:
正如 Ivo Beckers 在评论中提到的,这也可以写成一行:

CCHmac(kCCHmacAlgSHA1, keyBytes, strlen(keyBytes), baseStringBytes, strlen(baseStringBytes), digestBytes);

关于ios - Objective-C 中 HMAC SHA1 实现的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15976174/

相关文章:

用于检查铁路 PNR 状态和列车查询的 iPhone 应用程序

macos - Mountain Lion 中用两根手指拖动 IKImageView 和 NSScrollView

objective-c - 最佳实践? - 数组/字典作为核心数据实体属性

ios - 在 SWRevealViewController 中突出显示事件链接

ios - UITableViewCell 中的 UITextView,如何在 tableView 滚动时退出 textview 的 firstResponder?

ios - 可以从应用程序中读取企业 iOS 下载链接 plist 吗?

ios - 更改 Storyboard 中的 UIButton BorderColor

ios - rac_signalForSelector : needs empty implementation

objective-c - 为什么我的目标没有打印到控制台?

macos - 从 NSTextField 获取文本并将其设置为已定义的字符串