Frage

Ich habe den HMAC MD5 in meinem iPhone app zu implementieren. Die PHP-Version des Algorithmus (implementiert Server-Seite zur Überprüfung) ist hier und ich kann es nicht ändern (es ist eine API)

function hmac($key, $data) {
    $b = 64; // byte length for md5
    if (strlen($key) > $b) {
        $key = pack("H*",md5($key));            
    }
    $key = str_pad($key, $b, chr(0x00));
    $ipad = str_pad('', $b, chr(0x36));
    $opad = str_pad('', $b, chr(0x5c));
    $k_ipad = $key ^ $ipad ;
    $k_opad = $key ^ $opad;
    $message = $k_opad . pack("H*",md5($k_ipad . $data));
    return base64_encode(md5($message));
}

Ich fand ein paar Objective-C-Implementierung:

- (NSString *)HMACMD5WithKey:(NSString *)key andData:(NSString *)data
{

    const char *cKey  = [key cStringUsingEncoding:NSASCIIStringEncoding];   
    const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
    unsigned char cHMAC[CC_MD5_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgMD5, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
    NSString *hash = [Base64 encode:HMAC];
    return hash;
}

Haben die gleichen Ergebnisse nicht zurück (PHP! = ObjC).

Ich spielte mit ObjC Implementierungen die Länge auf 32 verdauen Veränderung (Ergebnis hat dann die gleiche Länge als PHP-Implementierung), die Schlüssellänge bis 64 (mit dem ersten str_pad entspricht), aber die Ergebnisse sind immer differents.

Kann mir jemand sagen, wie man das gleiche Ergebnis haben, in Objective-C ??

Edit: da die 2-Implementierungen in ObjC das gleiche Ergebnis zurück, nur ist hier nützlich ..

War es hilfreich?

Lösung

Wie pro meiner vorherigen Antwort, der PHP-Code implementiert eine Nicht-Standard-Variante des HMAC-Algorithmus. Diese Objective C-Code sollte es nachahmen. Getestet habe ich es auf Mac OS X 10.4.11 gegen den PHP-Code für zwei Kombinationen:

"ein kurzer Schlüssel"
"Some text"

„Das ist ein sehr langer Schlüssel. Es ist länger als 64 Bytes, die der wichtige Teil ist.“
„Das ist etwas sehr langer Text. Es ist länger als 64 Bytes, die der wichtige Teil ist.“

- (NSString *)HMACMD5WithKey:(NSString *)key andData:(NSString *)data {
    const char *cKey  = [key cStringUsingEncoding:NSASCIIStringEncoding];
    const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
    const unsigned int blockSize = 64;
    char ipad[blockSize], opad[blockSize], keypad[blockSize];
    unsigned int keyLen = strlen(cKey);
    CC_MD5_CTX ctxt;
    if(keyLen > blockSize) {
        //CC_MD5(cKey, keyLen, keypad);
        CC_MD5_Init(&ctxt);
        CC_MD5_Update(&ctxt, cKey, keyLen);
        CC_MD5_Final((unsigned char *)keypad, &ctxt);
        keyLen = CC_MD5_DIGEST_LENGTH;
    } else {
        memcpy(keypad, cKey, keyLen);
    }
    memset(ipad, 0x36, blockSize);
    memset(opad, 0x5c, blockSize);

    int i;
    for(i = 0; i < keyLen; i++) {
      ipad[i] ^= keypad[i];
      opad[i] ^= keypad[i];
    }

    CC_MD5_Init(&ctxt);
    CC_MD5_Update(&ctxt, ipad, blockSize);
    CC_MD5_Update(&ctxt, cData, strlen(cData));
    unsigned char md5[CC_MD5_DIGEST_LENGTH];
    CC_MD5_Final(md5, &ctxt);

    CC_MD5_Init(&ctxt);
    CC_MD5_Update(&ctxt, opad, blockSize);
    CC_MD5_Update(&ctxt, md5, CC_MD5_DIGEST_LENGTH);
    CC_MD5_Final(md5, &ctxt);

    const unsigned int hex_len = CC_MD5_DIGEST_LENGTH*2+2;
    char hex[hex_len];
    for(i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        snprintf(&hex[i*2], hex_len-i*2, "%02x", md5[i]);
    }

    NSData *HMAC = [[NSData alloc] initWithBytes:hex length:strlen(hex)];
    NSString *hash = [Base64 encode:HMAC];
    [HMAC release];
    return hash;
}

Andere Tipps

Zuerst Ihre „ObjC2“ wird mit SHA1, nicht MD5 (dies bedeutet, dass Sie wahrscheinlich einen Puffer, da SHA1 20 Bytes überrannt bekommen, während MD5 16 Bytes).

Zweitens denke ich, dass es eine Nicht-Standard-Variante ist in Ihrer PHP-HMAC-Implementierung. Beachten Sie, wie alle, aber die letzten Anrufungen von md5 () mit einer Packung ( „H *“, ...) eingewickelt? Alle aber die letzten Recht vor Base64-Codierung, das ist. Ich denke, das bedeutet, dass der PHP-Code ist Base64 codiert, die 'druckbaren hex' Darstellung der Daten (32 Bytes, die jeweils eine Hexadezimalzeichens in ASCII) nicht den 'raw' Wertes (16 Byte).

Da Sie nicht die PHP-Implementierung ändern können, Sie haben eine HMAC-Implementierung in Objective C zu schreiben, die die gleiche Nicht-Standard-Variante hat.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top