سؤال

ولقد لتنفيذ HMAC MD5 في بلدي iPhone التطبيق. النسخة PHP الخوارزمية (تنفيذ جانب الخادم للتحقق) هو هنا، وأنا لا يمكن تعديله (انها 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));
}

ولقد وجدت بضعة تنفيذ موضوعي-C:

- (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;
}

ولم نفس النتائج (PHP! = ObjC).

ولقد لعبت مع تطبيقات ObjC تغيير على هضم طول 32 (النتيجة ثم له نفس طول من تنفيذ PHP)، وطول المفتاح إلى 64 (المقابلة لstr_pad أولا) لكن النتائج بمختلف دائما.

ويمكن أن تقولوا لي كيفية الحصول على نفس النتيجة في الهدف C ؟؟

وتحرير: منذ 2 تطبيقات في ObjC تعود إلى نفس النتيجة واحدة فقط من المفيد هنا ..

هل كانت مفيدة؟

المحلول

وكما في إجابتي السابقة، رمز PHP ينفذ البديل غير قياسي من الخوارزمية HMAC. هذا الرمز C الهدف يجب تقليده. اختبرته على نظام التشغيل Mac OS X 10.4.11 ضد رمز PHP لهما معا:

و"قصيرة رئيسي"
"بعض النص"

و"هذا هو مفتاح طويل جدا، وهو أطول من 64 بايت، والذي هو جزء مهم."
"هذه هي بعض نص طويل جدا، وهو أطول من 64 بايت، والذي هو جزء مهم."

- (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;
}

نصائح أخرى

أولا، ك "ObjC2" يستخدم SHA1، لا MD5 (وهذا يعني انك ربما الحصول على تجاوز سعة المخزن المؤقت منذ SHA1 هو 20 بايت، بينما MD5 هو 16 بايت).

والثانية، وأعتقد أن هناك تفاوتا غير قياسي في تنفيذ PHP HMAC الخاص بك. لاحظ كيف أن كل ولكن مشاركة الدعاء من MD5) يتم تغليف (مع حزمة ( "H *"، ...)؟ ولكن كل واحد آخر الحق قبل ترميز Base64، وهذا هو. وأعتقد أن هذا يعني أن هو رمز PHP باستخدام Base64 ترميز 'عرافة طباعة "تمثيل البيانات (32 بايت، كل أرقام عرافة في ASCII) لا قيمة" الخام "(16 بايت).

وبما انك لا يمكن تغيير تنفيذ PHP، سيكون لديك لكتابة تنفيذ HMAC في الهدف C التي لديها نفس هذا الاختلاف غير قياسي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top