2011-09-29 196 views
0

下面的這個HMACSHA1代碼適用於將「密碼」和「消息」轉換爲AFF791FA574D564C83F6456CC198CBD316949DC9,作爲http://buchananweb.co.uk/security01.aspx的證據。C++ OpenSSL HMACSHA1的工作原理但不是我想要的方式

我的問題是,它是有可能的:

BYTE HMAC[] = {0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64}; 
BYTE data2[] = {0x4D,0x65,0x73,0x73,0x61,0x67,0x65}; 

,仍然可以得到相同的值:AFF791FA574D564C83F6456CC198CBD316949DC9

例如,如果我是一個服務器上接收到的數據包:

[HEADER] 08 50 61 73 73 77 6F 72 64 00 
[HEADER] 07 4D 65 73 73 61 67 65 00 

我撕裂50 61 73 73 77 6F 72 64 & 4D 65 73 73 61 67 65從包和使用這個對我的HMACSHA1。我將如何去做這件事來獲得正確的HMACSHA1值?

BYTE HMAC[] = "Password"; 
    BYTE data2[] = "Message"; 
    //BYTE HMAC[] = {0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64}; 
    //BYTE data2[] = {0x4D,0x65,0x73,0x73,0x61,0x67,0x65}; 
    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, HMAC, strlen((const char*)HMAC), EVP_sha1(), NULL); 
    HMAC_Update(&ctx, data2, strlen((const char*)(data2))); 
    HMAC_Final(&ctx, result, &result_len); 
    HMAC_CTX_cleanup(&ctx); 

    std::cout << "\n\n"; 


for(int i=0;i<result_len;i++) 
    std::cout << setfill('0') << setw(2) << hex << (int)result[i]; 

    int asd; 
    std::cin >> asd; 
// AFF791FA574D564C83F6456CC198CBD316949DC9 

編輯:

其工作原理是這樣:

BYTE HMAC[] = {0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64, 0x00}; 
BYTE data2[] = {0x4D,0x65,0x73,0x73,0x61,0x67,0x65, 0x00}; 

通過添加爲0x00,在最後。但是,我的問題更多的是將它從數據中剝離出來,然後使用它......它會一直很好嗎?

回答

2

問題是數組,字符串和空字符之間的關係。

當您聲明「密碼」時,編譯器在邏輯上將字符串文字視爲九字節數組{0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64,0x00}。當你調用strlen時,它會計算字節數,直到它遇到第一個0x00。 strlen(「密碼」)將返回8,即使技術上在字符數組中有9個字符。

所以當聲明的8個字節數組作爲末尾沒有空字節如下:

BYTE HMAC[] = {0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64}; 

的問題是,「strlen的(HMAC)」將計數至少8個字節,並保持計數在遍歷未定義的內存,直到它終於(如果有的話)命中一個零的字節。充其量,你可能會很幸運,因爲堆棧內存總是有一個填充數組聲明的零字節。更有可能它會返回比8更大的值。也許它會崩潰。

因此,當您從協議包中解析HMAC和MESSAGE字段時,您會計算實際解析的字節數(不包括終止空值)。並將該計數傳遞給hmac函數以指示數據的大小。

我不知道你的協議代碼,但我希望你沒有使用strlen來解析數據包,找出數據包內的字符串結束的位置。一個聰明的攻擊者可以注入一個沒有空終止符的包,並導致你的代碼做壞事。我希望你安全和仔細地解析。典型的協議代碼不包含內部打包字符串中的空終止字節。通常,「長度」被編碼爲一個整數字段,後跟字符串字節。使分析和確定長度是否會超過讀入的分組大小更容易。

+0

'int a_len = 9; int b_len = a HMAC_Init_ex(&ctx,HMAC,a_len,EVP_sha1(),NULL); HMAC_Update(&ctx,data2,b_len);' 這會更好嗎? – user954753

+0

a_len = 8; b_len = 7(因爲「密碼」的長度是8個字符,而「消息」是7個字符)。 – selbie

+0

謝謝,我會這樣做:-) – user954753

相關問題