Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c NSData中的NSString始终为空_Objective C_Macos_Sha_Hmac_Nsstringencoding - Fatal编程技术网

Objective c NSData中的NSString始终为空

Objective c NSData中的NSString始终为空,objective-c,macos,sha,hmac,nsstringencoding,Objective C,Macos,Sha,Hmac,Nsstringencoding,我想用HMAC SHA512签署一个请求,但我似乎搞乱了NSData和NSString之间的编码和解码。我拼命想弄清楚到底是什么错了,但我似乎没有弄清楚 伪代码: 我的实施: 以下是签名方法: +(NSString *)signRequestForParameterString:(NSString*)paramStr{ NSString *secret = @"7pgj8Dm6"; // secret is base64 encoded, so I decode it

我想用HMAC SHA512签署一个请求,但我似乎搞乱了NSData和NSString之间的编码和解码。我拼命想弄清楚到底是什么错了,但我似乎没有弄清楚

伪代码:

我的实施: 以下是签名方法:

+(NSString *)signRequestForParameterString:(NSString*)paramStr{

    NSString *secret = @"7pgj8Dm6";

    // secret is base64 encoded, so I decode it 
    NSData *decodedSecret = [secret base64DecodedData];
    NSString *decodedSecretString = [NSString stringWithUTF8String:[decodedSecret bytes]];

    NSData *data = [paramStr dataUsingEncoding:NSUTF8StringEncoding];
    NSString *dataString = [NSString stringWithUTF8String:[data bytes]];


    return [self generateHMACSHA512Hash:decodedSecretString data:dataString];

}
以下是哈希函数:

+(NSString *)generateHMACSHA512Hash:(NSString *)key data:(NSString *)data{


    const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
    const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];

    unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];

    CCHmac(kCCHmacAlgSHA512, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
                                          length:sizeof(cHMAC)];

    NSString *hash = [HMAC base64EncodedString];

    return hash;

} 

我很确定这是由于字符串的编码(decodedSecretString和dataString)<解码后的code>decodedSecretString(decoded base64)以ASCII编码。然而,当我调用散列方法时,我再次用ascii编码它,这将导致一个空错误。现在一切都让我困惑

您的密码无法解码为有效的UTF-8字符串,Java允许字符串中包含NUL字节,但当您将“Test\0消息”转换为C字符串并使用strlen时,其长度为4

像这样的方法应该会奏效:

+(NSString *)signRequestForParameterString:(NSString*)paramStr{
    NSString *secret = @"7pgj8Dm6";
    NSData *data = [paramStr dataUsingEncoding:NSUTF8StringEncoding];
    return [self generateHMACSHA512Hash:[secret base64DecodedData] data:data];
}

+(NSString *)generateHMACSHA512Hash:(NSData *)key data:(NSData *)data{
    unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA512, key.bytes, key.length, data.bytes, data.length, cHMAC);
    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
    return [HMAC base64EncodedString];
}

在执行HMAC或其他加密函数时,您应该建立一些基本的方法/函数,这些方法/函数不首先处理字符串。然后可以创建包装器方法,以方便的方式对字符串数据进行解码/编码或摘要

+ (NSData *)dataBySigningData:(NSData *)data withKey:(NSData *)key
{
  unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
  CCHmac(kCCHmacAlgSHA512, [key bytes], [key length], [data bytes], [data lenght], cHMAC);
  return [[NSData alloc] initWithBytes:cHMAC length:CC_SHA512_DIGEST_LENGTH];
}

+ (NSData *)dataBySigningMessage:(NSString *)message withKey:(NSData *)key
{
  return [self dataBySigningData:[message dataUsingEncoding:NSUTF8StringEncoding]
                         withKey:[key dataUsingEncoding:NSUTF8StringEncoding]];
}
(注意:此代码未经测试,只是在文本编辑器中拼凑而成)

不要担心键或数据的字符串表示形式。然后您可以从那里开始,例如获取摘要的base64编码


加密函数不关心字符串或文本编码。他们关心字节。字符串(在C中,因为它们以null结尾)只是数据中可以表示的内容的子集。因此,处理字符串将受到严重限制。

这需要检查大量代码。难道你不能稍微调试一下,弄清楚事情到底出了什么问题吗?如果你的秘密是Base64编码的,那么你应该对它进行解码,并将解码后的NSData传递给你的HMAC函数。不要将其转换回字符串。为什么要在
+signRequestForParameterString:
中将其转换回HMAC方法中的字节数组时,从NSString转换回NSData再转换回NSString?这有什么意义?只需将字符串传递给HMAC方法。您可能应该坚持使用UTF8,而不是ASCII,除非您知道您有ASCII文本,并且服务器无法理解UTF-8。难以置信!非常感谢你!
+(NSString *)signRequestForParameterString:(NSString*)paramStr{
    NSString *secret = @"7pgj8Dm6";
    NSData *data = [paramStr dataUsingEncoding:NSUTF8StringEncoding];
    return [self generateHMACSHA512Hash:[secret base64DecodedData] data:data];
}

+(NSString *)generateHMACSHA512Hash:(NSData *)key data:(NSData *)data{
    unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA512, key.bytes, key.length, data.bytes, data.length, cHMAC);
    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
    return [HMAC base64EncodedString];
}
+ (NSData *)dataBySigningData:(NSData *)data withKey:(NSData *)key
{
  unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
  CCHmac(kCCHmacAlgSHA512, [key bytes], [key length], [data bytes], [data lenght], cHMAC);
  return [[NSData alloc] initWithBytes:cHMAC length:CC_SHA512_DIGEST_LENGTH];
}

+ (NSData *)dataBySigningMessage:(NSString *)message withKey:(NSData *)key
{
  return [self dataBySigningData:[message dataUsingEncoding:NSUTF8StringEncoding]
                         withKey:[key dataUsingEncoding:NSUTF8StringEncoding]];
}