【问题标题】:Objective-C HMAC-256 To Sign HTTP Request - Seeing different resultsObjective-C HMAC-256 签署 HTTP 请求 - 看到不同的结果
【发布时间】:2014-07-03 07:52:33
【问题描述】:

我在 Objective-C 中使用 REST API,需要根据此规范 (https://web-payments.org/specs/source/http-signatures/) 对每个 HTTP 请求进行签名。

这一切看起来都很简单,但我很难获得正确的“签名”值应该是什么。我在 Objective-C 与其中一些在线 sha 生成器(http://www.freeformatter.com/hmac-generator.htmlhttp://hash.online-convert.com/sha256-generator)中得到了不同的结果。

我整理了一些沙盒测试代码,以便在我的项目之外解决这个问题。

这是我的测试代码:

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>

NSString * hmacSHA256(NSString *key, 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);
    NSMutableString *result = [NSMutableString string];
    for(int i = 0; i < sizeof cHMAC; i++) {
        [result appendFormat:@"%02x", cHMAC[i]];
    }
    return result;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSMutableString * data = [NSMutableString string];
        [data appendString:@"(request-line) get /\n"];
        [data appendString:@"date: Wed, 02 Jul 2014 22:12:37 GMT"];
        NSString * key = @"5a30f5477e2fdea27c5bdef8d5b0b13bfc8c2c77c608169da637a58ac0bff23895b58f8de5ef982a";
        NSLog(@"%@",data);
        NSString * signature = hmacSHA256(key,data);
        NSLog(@"signature: %@",signature);
    }
    return 0;
}

当我运行这个测试代码时,我得到这个作为签名:

8315081c226a7b0a77093cf12ec6ce4e112fedff12ddfcfd752c909b58a9ae5e

但是当我粘贴这些行时:

(request-line) get /
date: Wed, 02 Jul 2014 22:12:37 GMT

对于其中一个在线生成器(http://www.freeformatter.com/hmac-generator.htmlhttp://hash.online-convert.com/sha256-generator),这两个生成器都给了我相同的签名:

71b09a1d0b8cde88f2b0c5bb78a06c4539994435e5e47700aa56d2194b9c2f08

那么我应该如何将上述“unsigned char cHMAC”变量转换为正确的字符串?

谢谢。

【问题讨论】:

  • 不确定这是否是实际问题,但密钥不应该是实际密钥的十六进制表示,而不是 ASCII 表示吗? IE。您需要将十六进制解码为字节吗?
  • 另外,我很确定“(请求行)”并不是按字面意思包含的,它只是意味着您应该包含请求行本身。
  • 我的问题没关系。重要的是 objc 和在线生成器之间的区别。为什么我没有得到相同的签名。每个输入都相同,为什么结果不同..

标签: objective-c rest hmac sha256


【解决方案1】:

您的问题是文本中的行尾。实际上,您的程序正在生成正确的哈希值,但是您在网络工具中输入了一个 不同的 字符串,这就是您得到不同结果的原因。以下是您为程序提供的文本:

(request-line) get /\ndate: Wed, 02 Jul 2014 22:12:37 GMT

以下是您提供给网络工具的内容(假设您在 Windows 上这样做,根据我的测试进行检查):

(request-line) get /\r\ndate: Wed, 02 Jul 2014 22:12:37 GMT

注意“\r\n”。默认情况下,Windows(以及最有可能的所有 Web 浏览器)使用回车和换行符作为 EOL 序列。 Unix/Linux 只使用换行符,Mac 只使用回车。

如果您想检查任何其他哈希值,请在您的程序中添加一个“\r”进行测试,或者使用像 Notepad++ 这样的程序,您可以在其中控制行尾以创建文件,然后将它们上传到您的第二个站点列出来。

【讨论】:

  • 实际上它不是特定于 Windows 的(这里的 Safari Mac 上也是如此),它可能是所有平台上 textarea 的标准。
  • 是的,就是这样。一旦我将 \n 更改为 \r\n 它就是相同的签名。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 2018-08-30
  • 2022-01-10
  • 1970-01-01
  • 2016-11-23
相关资源
最近更新 更多