2017-04-13 48 views
0

我已經寫了一個c代碼,它取得了密鑰和消息的輸入值,並調用openssl hmac函數並生成mac代碼的結果。產生使用nist向量值作爲輸入的openssl hmac代碼的驗證系統

Key = 82f3b69a1bff4de15c33 
Msg = fcd6d98bef45ed6850806e96f255fa0c8114b72873abe8f43c10bea7c1df706f10458e6d4e1c9201f057b8492fa10fe4b541d0fc9d41ef839acff1bc76e3fdfebf2235b5bd0347a9a6303e83152f9f8db941b1b94a8a1ce5c273b55dc94d99a171377969234134e7dad1ab4c8e46d18df4dc016764cf95a11ac4b491a2646be1 

輸出:: 輸入值從NIST測試向量

#define KEY_SIZE 11   // in bytes 
#define MSG_SIZE 129   // in bytes 
#include <stdio.h> 
#include <string.h> 
#include <openssl/hmac.h> 

void str2hex(char *, char*, int); 

int main() { 
    char *key, *msg; 
    unsigned char keyy[KEY_SIZE], msgt[MSG_SIZE], temp[4]; 
    unsigned char* result; 
    unsigned int i, len = 20,Tlen = 10; 

    key = "";//values specified below 
    msg ="";//values specified below 
    /*CONVERT STRING TO HEX DIGITS - KEY*/ 
    str2hex(key, keyy, KEY_SIZE); 
    //CONVERT STRING TO HEX DIGITS - MSG*// 
    str2hex(msg, msgt, MSG_SIZE); 


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

    HMAC_CTX ctx; 
    HMAC_CTX_init(&ctx); 


    HMAC_Init_ex(&ctx, keyy, strlen(keyy), EVP_sha1(), NULL); 
    HMAC_Update(&ctx, (unsigned char*)&msgt, strlen(msgt)); 
    HMAC_Final(&ctx, result, &len); 
    HMAC_CTX_cleanup(&ctx); 

    printf("HMAC digest: "); 

    for (i = 0; i < Tlen; i++) 
    printf("%02x", result[i]); 

    printf("\n"); 

    free(result); 

    return 0; 
} 
//===================== string to hex conversion 
================================// 

void str2hex(char *str, char *hex, int len) { 
    int tt, ss; 
    unsigned char temp[4]; 
    for (tt = 0, ss = 0; tt < len, ss < 2 * len; tt++, ss += 2) { 
    temp[0] = '0'; 
    temp[1] = 'x'; 
    temp[2] = str[ss]; 
    temp[3] = str[ss + 1]; 

    hex[tt] = (int) strtol(temp, NULL, 0); 
    } 
} 

//---------------------------------------------------------------------------------// 

第一輸入給定的收集

HMAC digest: 1ba0e66cf72efc349207 

Nist_Mac = 1ba0e66cf72efc349207

它匹配,以便成功

但對於第二個輸入

Key = 4766e6fe5dffc98a5c50 
Msg = d68b828a153f5198c005ee36c0af2ff92e84907517f01d9b7c7993469df5c21078fa356a8c9715ece2414be94e10e547f32cbb8d0582523ed3bb0066046e51722094aa44533d2c876e82db402fbb00a6c2f2cc3487973dfc1674463e81e42a39d9402941f39b5e126bafe864ea1648c0a5be0a912697a87e4f8eabf79cbf130e 

輸出生成的:

HMAC digest: ca96f112a79882074b63 

Nist_Mac = 007e4504041a12f9e345

其failing.If任何一個可以檢查我的代碼,並請讓我知道我是什麼?做錯了這將是非常有益的。

回答

2

這裏有兩個問題。

首先是您對可能包含空字節的字符數組使用strlen。由於此函數計算字節數直到找到空字節,因此如果數組包含空字節(如第二個示例的情況),則不會得到期望的結果。

而不是在字節數組上使用strlen來確定長度,請使用數據的實際長度。由於要將包含十六進制數字的字符串轉換爲字節,因此字節數組的長度是輸入字符串長度的一半。

HMAC_Init_ex(&ctx, keyy, strlen(key)/2, EVP_sha1(), NULL); 
HMAC_Update(&ctx, msgt, strlen(msg)/2); 

還請注意,你應該通過msgtHMAC_Update,不&msgt,因爲後者是一個指向的數組。

第二個問題是在你的str2hex函數中。當你構造temp時,你沒有足夠的空間來終止空字節。這導致strtol,它期望一個以空字符結尾的字符串來讀取數組的末尾。這調用undefined behavior

在這種特殊情況下,您很幸運可以使用它,因爲temp後面的內存中的字節恰好包含空字節或非數字字節。你不能依賴這種行爲。通過使temp長一個字節並明確地將該字節設置爲0來解決這個問題。在處理它時,還應該修正函數參數中的有符號/無符號不匹配,並將temp的類型更改爲unsigned char陣列。

void str2hex(char *, unsigned char*, int); 

... 

void str2hex(char *str, unsigned char *hex, int len) { 
    int tt, ss; 
    char temp[5]; 
    for (tt = 0, ss = 0; tt < len, ss < 2 * len; tt++, ss += 2) { 
    temp[0] = '0'; 
    temp[1] = 'x'; 
    temp[2] = str[ss]; 
    temp[3] = str[ss + 1]; 
    temp[4] = 0; 

    hex[tt] = strtol(temp, NULL, 0); 
    } 
} 
0

在消息的字節位置58處,您有一個0x00字節(空)。既然你做一個strlen(msgt),這將導致58,而不是128的摘錄從文檔(重點礦山):

C庫函數size_t strlen(const char *str)計算字符串str 的長度可達,但不包括終止空字符

只要使用正確的消息長度,並且不要在不包含可打印字節的char數組上使用字符串操作。