2017-04-13 7 views
0

키의 입력 값을받는 c 코드를 작성했으며 message는 openssl hmac 함수를 호출하고 mac 코드의 결과를 생성합니다.ns 벡터 값을 입력으로 사용하는 openssl hmac 코드의 유효성 검사 시스템

Key = 82f3b69a1bff4de15c33 
Msg = fcd6d98bef45ed6850806e96f255fa0c8114b72873abe8f43c10bea7c1df706f10458e6d4e1c9201f057b8492fa10fe4b541d0fc9d41ef839acff1bc76e3fdfebf2235b5bd0347a9a6303e83152f9f8db941b1b94a8a1ce5c273b55dc94d99a171377969234134e7dad1ab4c8e46d18df4dc016764cf95a11ac4b491a2646be1 

출력이 생성 : 입력 값이 첫 번째 입력은 주어진

#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); 
    } 
} 

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

NIST 시험 벡터로부터 수집

HMAC digest: 1ba0e66cf72efc349207 

Nist_Mac를 = 1ba0e66cf72efc349207

는 너무 성공 일치

그러나

Key = 4766e6fe5dffc98a5c50 
Msg = d68b828a153f5198c005ee36c0af2ff92e84907517f01d9b7c7993469df5c21078fa356a8c9715ece2414be94e10e547f32cbb8d0582523ed3bb0066046e51722094aa44533d2c876e82db402fbb00a6c2f2cc3487973dfc1674463e81e42a39d9402941f39b5e126bafe864ea1648c0a5be0a912697a87e4f8eabf79cbf130e 

출력이 생성 된 두 번째 입력 :

HMAC digest: ca96f112a79882074b63 

Nist_Mac = 007e4504041a12f9e345

그 failing.If 내 코드를 확인하고 친절하게 내가이 누구인지 알려 줄 수있는 하나 잘못하면 정말 도움이 될 것입니다.

답변

2

여기에는 두 가지 문제가 있습니다.

첫 번째는 널 바이트를 포함 할 수있는 문자 배열에 strlen을 사용하고 있다는 것입니다. 이 함수는 null 바이트를 찾을 때까지 바이트 수를 계산하기 때문에 배열에 null 바이트가 들어 있으면 (두 번째 예와 같이) 예상 한 결과를 얻지 못합니다.

바이트 배열에서 strlen을 사용하여 길이를 결정하는 대신 데이터의 실제 길이를 사용하십시오. 16 진수를 포함하는 문자열을 바이트로 변환하기 때문에 바이트 배열의 길이는 입력 문자열의 길이의 절반입니다. 후자는 배열에 대한 포인터는 당신이, msgt&msgt하지, HMAC_Update에 전달해야하는 것도

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

참고.

두 번째 문제는 str2hex 기능에 있습니다. temp을 만들 때 종료 널 바이트를위한 충분한 공간이 없습니다. 이로 인해 Null 종료 문자열을 예상하는 strtol이 배열 끝을지나 읽을 수 있습니다. 그러면 undefined behavior이 호출됩니다.

이 특별한 경우에는 temp 다음에 오는 메모리의 바이트가 null 바이트 또는 숫자가 아닌 숫자로 포함되어 있기 때문에 "운이 좋으면"작동합니다. 그러나이 동작에 의존 할 수는 없습니다. temp을 1 바이트 더 길게 만들고이 바이트를 명시 적으로 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 바이트 (null)를가집니다. 당신이 strlen(msgt)을 다하고 있기 때문에,이 문서 (강조 광산)에서 128 발췌 대신 58 결과 :

C 라이브러리 기능 size_t strlen(const char *str)가 최대 문자열 str을 의 길이를 계산하지만, 포함하지 않음 종료 null 문자.

메시지의 적절한 길이를 사용하고 인쇄 가능한 바이트를 포함하지 않는 문자 배열에 문자열 연산을 사용하지 마십시오.