2013-12-19 49 views
1

我試着下面的代碼。事情是:有些時候工作,有些時候不工作!我正在使用OpenSSL庫,但我相信我的錯誤是簡單的,與C有關。初學者的C++內存分配混亂

int test_c(string to_sign, string key) 
{ 
    const void* key_void = (const void*)key.c_str(); 
    int key_size = key.size(); 

    const unsigned char* data_char = (const unsigned char*)to_sign.c_str(); 
    int data_size = to_sign.size(); 

    unsigned int res_f_len = data_size*8; 
    unsigned char* res_f = (unsigned char*) malloc(sizeof(unsigned char)*res_f_len); 

    HMAC_CTX ctx; 
    HMAC_CTX_init(&ctx); 
    HMAC_Init_ex(&ctx, key_void, key_size, EVP_sha256(), NULL); 
    HMAC_Update(&ctx, data_char, data_size); 
    HMAC_Final(&ctx, res_f, &res_f_len); 
    HMAC_CTX_cleanup(&ctx); 

    return strlen(res_f); 
} 

當我說這是行不通的,我的意思是,對於相同的數據和關鍵,不同的結果返回!

+0

如果這是C,那麼你不需要在'void *'s(包括'malloc()')的返回值。如果這是C++,請不要用'c'標記。 – 2013-12-19 00:29:35

+0

對不起,它的C++ – Blazer

+2

您使用strlen(res_f)表示結果字符串大小未知。 HMAC函數是否填充/零res_f?如果不是,malloc會返回一個指向充滿未定義值(如in,garbage)的內存的指針,strlen通過查找0來工作。 – Warty

回答

1

而不是返回strlen(res_f);作爲輸出緩衝區的長度,您需要返回res_f_len

有三樣東西在你的代碼strlen()可能發生:

  • 如果HMAC消息摘要有等於零,strlen會返回一個長度,它比HMAC消息摘要短的字節。
  • 如果HMAC消息摘要沒有零個字節,則strlen將讀取超出消息摘要,從而導致兩種結果之一:
    • strlen的消息後,在內存中讀取通過垃圾消化,最終在隨機停止0. strlen返回的值太大。
    • 如果你非常幸運,消息摘要後的第一個字節是0,在這種情況下,strlen返回消息摘要的實際長度。

因此,只有在最後一個場景,你會得到正確的值。這似乎很錯誤。

看起來HMAC_Final會更新傳遞給它的長度參數。 (See the example in the top-voted answer to this StackOverflow question。)這就是爲什麼你傳遞一個指針到int。你應該只返回這個更新的值。

+0

Owh,在浪費了大約10個小時的時間之後,搞砸了我的整個程序,這真的就是你在這裏寫的!!!謝謝! – Blazer