2008-10-28 92 views
10

我試圖設置HMAC-SHA-256哈希的基本測試,但是我在引擎設置上遇到了問題。理想情況下,我想只設置HMAC-SHA算法,但到目前爲止我還沒有得到加載所有算法的一般情況。目前,我正在嘗試設置默認摘要的行上收到段錯誤。另外,我經常是一個Java人,所以不要猶豫,指出代碼中的任何錯誤。在OpenSSL中瞭解引擎初始化

#include <openssl/hmac.h> 
#include <openssl/evp.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main() { 
    unsigned char* key = (unsigned char*) "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"; 
    unsigned char* data = (unsigned char*) "4869205468657265"; 
    unsigned char* expected = (unsigned char*) "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"; 
    unsigned char* result; 
    HMAC_CTX* ctx; 
    ENGINE* e; 

    ENGINE_load_builtin_engines(); 
    ENGINE_register_all_complete(); 
    ENGINE_set_default_digests(e); 

    HMAC_CTX_init(ctx); 
    HMAC_Init_ex(ctx, key, 40, EVP_sha256(), e); 
    result = HMAC(NULL, NULL, 40, data, 16, NULL, NULL); 
    HMAC_CTX_cleanup(ctx); 

    ENGINE_finish(e); 
    ENGINE_free(e); 

    if (strcmp((char*) result, (char*) expected) == 0) { 
    printf("Test ok\n"); 
    } else { 
    printf("Got %s instead of %s\n", result, expected); 
    } 
} 

編輯:該項目現在已經發展到了下面,但我仍然在HMAC_Init_ex段錯誤:

unsigned char* key = (unsigned char*) "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"; 
unsigned char* data = (unsigned char*) "4869205468657265"; 
unsigned char* expected = (unsigned char*) "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"; 
unsigned char* result; 
unsigned int result_len = 64; 
HMAC_CTX ctx; 
ENGINE* e; 

result = (unsigned char*) malloc(sizeof(char) * result_len); 
e = (ENGINE*) ENGINE_new(); 

ENGINE_load_builtin_engines(); 
ENGINE_register_all_complete(); 
ENGINE_set_default_digests(e); 

HMAC_CTX_init(&ctx); 
HMAC_Init_ex(&ctx, key, 16, EVP_sha256(), e); 
HMAC_Update(&ctx, data, 40); 
HMAC_Final(&ctx, result, &result_len); 
HMAC_CTX_cleanup(&ctx); 

ENGINE_finish(e); 
ENGINE_free(e); 

回答

13

正如Martin所說,您的原始建議存在的問題是您需要初始化ENGINE。編輯代碼的問題在於你正在執行ENGINE_new,這會讓你獲得一個全新的ENGINE引擎,然後你需要提供密碼方法,摘要方法等等。實際上,你想要什麼(以及什麼幾乎每個人都想),只是完全忽略了所有引擎的東西是正確的選擇。

一些附屬的問題:

  • 你的字符串是十六進制,但你需要每一個字符\ X在字符串中的這個位置,我懷疑是你想要什麼真正得到的是十六進制字節。
  • 你試圖從「數據」散列40個字節,這並不是那麼長(實際效果:你最終會部分散列結果字符串)
  • 你的預期結果是(據我所知)不正確
  • 您將打印出隨機字符到終端,因爲HMAC函數將產生32字節的隨機二進制數據,而不是可打印的東西。

以下代碼編譯,工作並通過測試。這是給你找到了(因爲它仍然採用了單獨的HMAC_ *功能 - 如果你想通過位使用HMAC_Update做你的散列位很有用)的示例代碼有點不同:

#include <openssl/engine.h> 
#include <openssl/hmac.h> 
#include <openssl/evp.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 


int main(void) 
{ 
     unsigned char* key = (unsigned char*) "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; 
     unsigned char* data = (unsigned char*) "\x48\x69\x20\x54\x68\x65\x72\x65"; 
     unsigned char* expected = (unsigned char*) "\x49\x2c\xe0\x20\xfe\x25\x34\xa5\x78\x9d\xc3\x84\x88\x06\xc7\x8f\x4f\x67\x11\x39\x7f\x08\xe7\xe7\xa1\x2c\xa5\xa4\x48\x3c\x8a\xa6"; 
     unsigned char* result; 
     unsigned int result_len = 32; 
     int i; 
     HMAC_CTX ctx; 

     result = (unsigned char*) malloc(sizeof(char) * result_len); 

     ENGINE_load_builtin_engines(); 
     ENGINE_register_all_complete(); 

     HMAC_CTX_init(&ctx); 
     HMAC_Init_ex(&ctx, key, 16, EVP_sha256(), NULL); 
     HMAC_Update(&ctx, data, 8); 
     HMAC_Final(&ctx, result, &result_len); 
     HMAC_CTX_cleanup(&ctx); 

     for (i=0; i!=result_len; i++) 
     { 
       if (expected[i]!=result[i]) 
       { 
         printf("Got %02X instead of %02X at byte %d!\n", result[i], expected[i], i); 
         break; 
       } 
     } 
     if (i==result_len) 
     { 
       printf("Test ok!\n"); 
     } 
     return 0; 
} 

當然,這不回答關於如何初始化引擎的原始問題,但沒有更多的上下文真的沒有正確的答案,哪些上下文結果不是在您的情況下相關...

0

看起來好像沒有什麼分配發動機,所以在第一次使用的e是segfaulting。我認爲你需要先致電ENGINE *ENGINE_new(void)

(請注意,我用的OpenSSL,但我以前沒有使用過的ENGINE功能。)

更新:我不是我自己的答案真的很高興(我必須趕寫到茶之前)。所以我還注意到有:

  1. 我已經有點看(長)man pageENGINE功能的,我不太清楚,調用ENGINE_new就足夠了。

  2. 我沒有注意到對HMAC_CTX_*函數的調用採用了未初始化的指針,而不是指向已分配結構的指針。 HMAC_CTX_init將嘗試寫入由其參數ctx指向的內存,這將會出現段錯誤。您需要聲明和使用ctx這樣的:

    HMAC_CTX ctx; 
    HMAC_CTX_init(&ctx); 
    HMAC_Init_ex(&ctx, key, 40, EVP_sha256(), e); 
    ... 
    

    這樣你在棧上分配的結構,然後將指針傳遞給它。

  3. HMAC功能不從全局或線程本地存儲需要一個指向CTX可言,所以分開,我不知道它是連接到CTX的。我想你可以通過調用HMAC_Update一次或多次,然後通過HMAC_Final來獲得結果。你需要爲結果分配空間,所以像下面將針對工作:

    unsigned int len; 
    HMAC_Final(&ctx, result, &len); 
    
+0

感謝您的建議馬丁,我試過了他們出來,但我仍然卡住了。我很好奇關於您還沒有使用它的ENGINE評論。是否可以在沒有引擎的情況下使用OpenSSL? – Fylke 2008-10-28 14:07:28

1

好了,原來你沒有使用一個引擎,但我會誤解究竟如何不使用明確的引擎。我也誤解了如何正確地格式化測試向量。最後,我看了一下hmactest.c,這幾乎是我想做的事情,我只是不理解代碼。

最終的解決方案是什麼,我試圖做的是這樣的:

int main() { 
    unsigned char* key = (unsigned char*) "Jefe"; 
    unsigned char* data = (unsigned char*) "what do ya want for nothing?"; 
    unsigned char* expected = (unsigned char*) "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"; 
    unsigned char* result; 
    unsigned int result_len = 32; 
    int i; 
    static char res_hexstring[32]; 

    result = HMAC(EVP_sha256(), key, 4, data, 28, NULL, NULL); 
    for (i = 0; i < result_len; i++) { 
    sprintf(&(res_hexstring[i * 2]), "%02x", result[i]); 
    } 

    if (strcmp((char*) res_hexstring, (char*) expected) == 0) { 
    printf("Test ok, result length %d\n", result_len); 
    } else { 
    printf("Got %s instead of %s\n", res_hexstring, expected); 
    } 
} 

但因爲我是問完全不同的東西,我不能確定什麼用原來的問題做。建議?

+0

NULL。注意:爲md傳遞NULL值以使用靜態數組不是線程安全的。 https://www.openssl.org/docs/man1.0.2/crypto/hmac.html – codenamezero 2018-01-29 15:42:11