Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.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
Php 基64字母表中的正斜杠导致生成哈希时出现问题_Php_Objective C_Json - Fatal编程技术网

Php 基64字母表中的正斜杠导致生成哈希时出现问题

Php 基64字母表中的正斜杠导致生成哈希时出现问题,php,objective-c,json,Php,Objective C,Json,我正在构建一个库,与驱动我们iPad客户端的后端进行通信 所有请求的基本结构是: { "metaData":{ JSON Object that is not important for this question }, "requestData": { "nonce":"random string", "params":"JSON string containing request data" }

我正在构建一个库,与驱动我们iPad客户端的后端进行通信

所有请求的基本结构是:

{
    "metaData":{ JSON Object that is not important for this question },
    "requestData":
        {
            "nonce":"random string",
            "params":"JSON string containing request data"
        }
     "checksum":"hash of JSON string representing value of requestData",
     "connectionString":"someIdentifier"
}
对于我遇到问题的特定情况,当requestData具有以下结构时:

{
    "requestData":
        {
            "nonce":"random string",
            "params":
                "{\"userId\":1,\"formData\":\"encrypted string, then Base 64 encoded on iPad\"}"
        }
    "checksum":"hashed value of string representation of requestData"
}
用于生成校验和的字符串示例(由
NSLog
打印)如下:

{"params":"{\"groupId\":3,\"formData\":\"SExvR0J1ZkJSQkhObU5xZkiEXdBede2moVN3LtMDZlxcXYVj7Uz!BFdiQC9SwxIhrrcGv2GtWJzjqMhHzdFDZW568tbnLTKQ9931efrpjtvqlK9mudInXj0FQdBLY0M6f9zBlLu6TcQ7sA6AD15DF0HyUPIi4fnc90ZV7omGqRpyI412aGSpDPJEbCUBSY5WMUFJqRstyK1+Qo0vmN8uMprztDIyEFufP24DHHtYZHVAic8Sg8CxbsUTTYDgDc!0ASQwahEgy1sWkMP!BVpK8VU7quXDdIJrxbSNL7OO4tsJrHIXyhhK7ZUNKMaZX+fBSdw6DbNtTM86K0X4NSRXPVLE0EAklAJ2OpMDBsoz9k!jhCba5gRXY7r48USpsMyyj1v8SsDKn58FsvDxsdCrPY77KmIX3Icy!n3iA!lBfc3ol6c90wkwPSqNvnO7uRDYrfbP1c0zRYSXbLTQvHLLdfAWKariCKtNg6YAXNfgQ6lWFRXce8flHgUz6E7rkt9tjc9i4K+EjcL10H+E3AGkidYPGtQOm1vey!M8oineM!Cgg3VcvNCv!yN90iq3T+tqI0ivvBnh+1aCw2H90tnNm8Gi+XCrIdhORN3QjSkkNbpfoSCLoIkuBmXlNuTskaJ4nnV3kHrmU!4hYMeZIIZ8OnZWPpU47xJi!kh3MDdI2c+WorT+y+M5XwcQO6jGv3tXyRVBy!ne+sSnU!InISm7x1VQjJLmjULMnqxRDoZatBsofxICJysEUaDJvgwZasMJpQk1zyrPraBWBJ0lVVaWhH5OTi6U0!hHNVs5Xf+H23JxmPpUNWqNvsAGfnTfY!kSoiLoSxEocICK8zsJFMc69101DNAanayf!MjFFDeFRlzpKhcRON7cxDfvBdSoc9hL1lcMzFbLemrL1w8jNNMfKlY7QDZ5ebOERJMjY0!o8znlxOa0ViuJ++O7+QrT!mGdSQYGh3NJ3MK1IdJkXuFpY!guyXOgohTsqcD0DZSk84OsI76L18snFvs4qMHw9SUf3l0jWPxbTYimmlM3DVUR7Sn7xOsGmQGcwpGK1tinlIDA+w8Ci+CLWESsjZ5QDQCr\",\"internalFormId\":\"MTN13511759141\",\"userId\":1,\"code\":\"\",\"_queuedSubmission\":false,\"groupName\":\"LDMAdmin\",\"saleType\":\"1\",\"formTableName\":\"myTableName\",\"emailName\":\"default\"}","nonce":"XqfK9Nxwuggw4m"}
当我检查服务器日志时,我发现设备上生成的校验和不等于服务器上生成的校验和(在PHP中,区分大小写不是问题),因此身份验证失败

发生故障的结构示例如下:

PageManager.m - 905 -> Final Request:
{
    "checksum":"9D51170D1510C4081936870D11E96C869DB26B895393B9C14B2A6BC3C1F10F23",
    "connectionString":"testBed",
    "metaData":
        {
            "accessToken":"myAccessToken",
            "appId":"myAppID",
            "deviceId":"1X:1X:1X:1X:1X:1X",
            "groupId":3,
            "groupName":"LDMAdmin",
            "timestamp":1351018002.780379,
            "userId":1,
            "useragent":"iPhone OS",
            "username":"admin"
        },
    "requestData":
        {
            "nonce":"1iezcBdjbE",
            "params":"{\"groupId\":3,\"formData\":\"Tnh3dWdndzRtRmdxSFNmN/NXCIQSukpx3+mhmbNQh0PTGbLlEFoDinyrq3wRJGZ+8sQ/+xcjS4cU7evluipxqQDZIOvp4ZcoDnxTPeqBZJrG/bq5FHR6PVCYK2DaLHfj025z/H3RM8dUEoWcrTLqSUcW+E7Mfl8ZCApqJMxSa8eYYqLT7tm7r1SC+bjXNOQZLTC2laFhihQ5hLKqFFnO/z3AlUYAAUhKKD1lWIipnJUUNoyHdWuuOobMSS1ZZP5f5f+RTFsmGZUDe6qX6h2cjIQ2+VGPIsP//gqwO4iDx/FdHD+xrjCyEgL2Va/m/Z+ANxCr3DN2o2Jnwg8B8QycFN2tGrgusseAgoa9Ng9LRgooZW+KuECWDhorHzvuv2rOlhOskymj4XTu8890ZMJbcr1Ic6zwztm82R1qKaoy1o6gIbUNtVZFSqUlP8TO7mWHKr3Y8Awn7ih9HzSOg1486EDL4OjfOR9J2pw1jbK7ZJb7LxzrWFgoyrwDBAw3q7PrV4Ml9ngI6oXOh3veAq/wulyBOdF46n7evqIkAKg4FYdvzmFKd2bgOpxwBlAI7vL2IiC4v8GXI5977SkPPEKUZHXWmfrgr/VzF79gIxJDqV9N0ceAcgY8bWbBXf7DLd9H82obFa60yZBo5/MBjq9SNuD08vJEEauVGs4wfDr9+xzsr3z+plqxAejODdxKfF48Ra21L8Xozozv5papTP9cpGVU11mCWj+no5gtM0VQKRB7IQcpDWjQgQyThN2aoE06ecA2gY5SSXN0XHVRw5OKM0/rlNIuMiqow5wqHLl41IzDSF2HuJKj06Lv8t5CLLOd9rkOjYw6w8SrbsZeG5jwagJkyQ0UuKu+PIoIc2DJnUWDC5iqlb0TO9nPDNFKad+MYlfgDR0CxR+3ddkqWNBNSW5rsh5QZDlJHDjhQFLkuqiiRAnMvKOcbqAnXIZ9EuAo/DkcmtGPHkEyEaA2cb3mXysBP49jhY0m/qinloza+j3d7Kb/Fu35U929fOxH6+W+5oZv/r+a9KvkDhPoRwiFouVwTtTOwbjVDT+NEg2OUfDaEYbQ/RbM7i6X+XjSkZMLYsRs1Q9CwdBabY860uBNFQ==\",\"internalFormId\":\"MTN13510178111\",\"userId\":1,\"code\":\"\",\"_queuedSubmission\":false,\"groupName\":\"LDMAdmin\",\"saleType\":\"1\",\"formTableName\":\"myTableName\",\"emailName\":\"default\"}"
        },
    "url":"http://myurl.com/myAction"
}
formData
是通过创建所需数据的
JSON
字符串,加密该字符串,并将生成的
NSData
对象编码为base 64字符串来生成的。
checksum
是通过获取表示
requestData
值的
JSON
字符串的哈希值(使用SHA256)生成的

requestData
转换为JSON字符串,并使用以下内容进行散列:

+(NSString *)hmacSHA256:(NSString *)string withKey:(NSString *)key {
    NSString *hash = 0;
    NSData   *hmac = 0;

    NSMutableString *temp = [[NSMutableString alloc] initWithString:@""];

#ifdef DEBUG
    NSLog( @"%s - %d -> Values:\nString:  %@\nKey:  %@", __FILE__, __LINE__, string, key );
#endif


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

    unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
    unsigned char *digest;
    unsigned int  dLength;

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

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

    digest  = (unsigned char *)[hmac bytes];
    dLength = hmac.length;

    for ( int i = 0; i < dLength; ++i )
        [temp appendFormat:@"%02X", digest[i]];

    hash = [[NSString alloc] initWithString:temp];

    return hash;
}
将哈希与请求中发送的哈希进行比较

服务器日志的一个示例:

ERROR - 2012-10-23 21:31:16 --> Encoded Checksum recieved is: 14F03A1DCAEA9DBBC7EC8CA1D666D89C391760AA246C91B52164D526AC83E5E5
DEBUG - 2012-10-23 21:31:16 --> Model Class Initialized
DEBUG - 2012-10-23 21:31:16 --> Model Class Initialized
DEBUG - 2012-10-23 21:31:16 --> Database Driver Class Initialized
ERROR - 2012-10-23 21:31:16 --> encoded string is: {"params":"{\"groupId\":3,\"formData\":\"SE5tTnFmWHFmSzlOeHd1ZyYzHN9y\/aJSbsqEn6X1TypGwWcXtXGpW4ODrCDVwZyIjhq3oOeZ4C6hGCDFGqHsa5hhNXxeerWLG5SyvfksCTG1+GCvWFwMx0CzZwOAfJRwSoCBCaeZ\/pivs3dHQS22SEbWn6+2e2vayeap7mxvZZw9Jrl\/c4dGFAiNqQB5pQbNO661AqbJWDAHCS8EWBhXXsd0SbTHlZAip4H0MdlF2rnElCVfHlc01RcuJNXLF3NJvfjY9m4sXmI3BAED0c0C\/i0Uw2M6pe4iDJv\/OvOI0NVS8RKbRbjhTo3oktAmNttfKTG6xp0wMhbANppuoo4QY3XwQ5BKUjqhmr5kx8j0RTmebcTCmxsC9h1dqjHYnf1JnZDFATkVsKnn\/Ela1wSjhGL7uP6jl3r4xDGKGPWDj0E3iAPNN56pmJxzyQrHOOqUzGbmvU3qj7Ul039IGYZTzn74VUkWi3JsxJH+kU9iWSvuC+YoOHcf\/0OFn1PqBoDHjDTbN+3HV8wwSqrVFJ6z9RX4MwRfffVgKl8xL2hHqBnegjvyd65KbZbSd\/3OrEBeL0dAjuARiPioNTpjzwga4chFRA471gweLT+cKweZBXZMYll36sNqulIBzbCmqbndDk63Id9iSrs9\/fQVWUA7RJDudnAxvQPs8gTznp9Dz1SomyY4ONYrJ9EticAEnUEjF2sCdejYlgu61a3Zss19m+MzgEhxkwmRwttsRbFfNK44wP\/wB2FgdfjsY94nHpJ+6lPEZtRmWpYtNVxQMVC6mMde6CbSEem71byIiN424baPImtNIfF+bKl6BKxyEl7BhI3z25NXaKyfaflzxGY8Yvdg0f73SfT3omPP3KxdudFgJrQ6eiO2AXt5L6lPjezjRr17R6hTUNmYwvZ3C5S0zoY7ynmCHebeiNlavVepUBkn0Iu6w\/qKDJ5wr80n7XX3EXuo1ODCC5aCjOSr+gSS9eVm0\/IBQNF\/ec4kjI29LRyrOFOS\/2poHY9XzyagVURiwi101a0yPETRRsC8n4B\/XFmOFQ0VcCQNgTuXute52fsccxB3DkV7ixBbQ8mt6o2XDWGk2HnrDwmRuNX87rBHow==\",\"internalFormId\":\"MTNC13510277491\",\"userId\":1,\"code\":\"\",\"_queuedSubmission\":false,\"groupName\":\"LDMAdmin\",\"saleType\":\"1\",\"formTableName\":\"myTableName\",\"emailName\":\"default\"}","nonce":"gw4m"}
ERROR - 2012-10-23 21:31:16 --> Encoded Checksum expected is: 8d999d76e48907905e701da3ccdbccb4061d05ed5a7c18b58507b6e6352fb1f5
但是,应用程序的其他组件使用相同的结构(减去base64编码),其行为与设计和预期相同。使用与上述示例相同的方法和键生成
校验和。例如:

{
    "requestData":
        {
            "nonce":"random string",
            "params":"{\"latitude\":37.7,\"longitude\":-122.4}"
        }
    "checksum":"hashed value of the string representation of requestData"
}
我不知道为什么服务器上的PHP脚本会在上面提到的失败案例中生成不同的散列。以前有人遇到过这种问题吗

更新:

我使用
SBJson
将数据结构编码和解码为JSON字符串()

更新2:

根据到目前为止的讨论,无法保证JSON对象(或者在我的例子中是
NSDictionary
)序列化为
JSON
字符串的顺序。但如果是这样的话,我不明白为什么在以明文形式发送数据的情况下,服务器上会生成相同的哈希,而在某些数据是以base 64字符串的形式的情况下,服务器和客户端之间会生成不同的哈希

唯一的解决方案(可能不是正确的解决方案)是从基本64字母表中删除
/
(我将其替换为
)。我敢肯定,在服务器端尝试解码字符串时,这会导致问题

在这一点上,我想了解正斜杠是如何导致这个问题的。

没有“表示某某的JSON字符串”。如果内存中有一个数据结构,并在其上使用平台的默认JSON序列化程序,则无法保证它将生成与另一个平台的默认JSON序列化程序相同的字符串,甚至无法保证它将生成与您明天或闰年的星期五使用的JSON序列化程序相同的字符串


JSON为序列化程序提供了相当大的空间来放置空白、如何格式化数字、发出对象字段的顺序等等。它不能用作对底层抽象数据集进行散列的基础。

编码表中的正斜杠,不知何故,在php代码中生成散列时会导致冲突

我的目标C代码中的原始表格:

//64 digit code
static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
我必须用以下内容替换:

//64 digit code
static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+!";

这可能只是一个临时的解决方案,因为它声明在base64编码的字符串中可以接受正向斜杠。只需替换正斜杠就解决了目前的问题。

我相信,除非您向我们展示计算散列的代码,否则没有人会有想法。显然这里出了点问题。第一个错误可能是您实际上在某个地方解码了字符串,然后在检查哈希之前将其再次编码为JSON。这可能最终会更改字符串,破坏哈希。第二件事是:我看不出您是否意外地将校验和值传递到PHP哈希中。当然应该删除,但在字符串级别。调试的第一步是检查两种哈希实现在常量字符串(即相同的字节!)上使用时是否提供相同的结果。@Sven我检查了服务器代码,它正在以正确的顺序解码元素。另外,如果我以明文形式发送数据,身份验证将通过,因此我认为错误在加密中。@Sven在base 64编码字符串中使用正斜杠导致了意外行为。但这可能会导致解码问题。您始终可以对字符串进行散列,但之后将散列值添加到该字符串将改变它。如果您没有正确地反转此过程,您将无法返回用于哈希的原始字符串。@Sven:问题是您可能会得到不同的字符串作为同一JSON对象的JSON表示形式。如果散列不同的字符串,通常会得到不同的散列。这并不能解决真正的问题,即您无权期望两个不同的JSON序列化程序首先生成相同的字符串表示。您无权期望一个JSON序列化程序在周二生成与周一相同的数据字符串表示形式。这不仅仅是理论上的;序列化程序可以根据对象的实现内部哈希表表示的不可预测排序行为来选择对象中字段的表示顺序。在您的示例中,序列化程序显然没有按排序顺序发送字段——它在“formData”之前有“groupId”,并且“nonce”之前的“params”。@HenningMakholm如果是这样的话,那么为什么未加密的字符串会通过身份验证?x@Mike:不确定在本文中“加密”是什么意思。@HenningMakholm抱歉,为什么纯文本会通过身份验证而不是完全相同的身份验证
//64 digit code
static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+!";