C++ C++;OpenSSL HMACSHA1可以工作,但不是我想要的工作方式

C++ C++;OpenSSL HMACSHA1可以工作,但不是我想要的工作方式,c++,visual-c++,packet-capture,hmac,hmacsha1,C++,Visual C++,Packet Capture,Hmac,Hmacsha1,下面的HMACSHA1代码用于将“密码”和“消息”转换为AFF791FA574D564C83F6456CC198CBD316949DC9,作为证据 我的问题是,是否有可能: BYTE HMAC[] = {0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64}; BYTE data2[] = {0x4D,0x65,0x73,0x73,0x61,0x67,0x65}; 并且仍然得到相同的值:AFF791FA574D564C83F6456CC198CBD316949DC9

下面的HMACSHA1代码用于将“密码”和“消息”转换为AFF791FA574D564C83F6456CC198CBD316949DC9,作为证据

我的问题是,是否有可能:

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
我从数据包中取出
506173776f7264
&
4d657373616765
,并将其用于我的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

通过在末尾添加0x00。但是,我的问题更多的是从数据中提取数据,并使用它。。。还可以吗?

问题是数组、字符串和空字符之间的关系

当您声明“Password”时,编译器在逻辑上将字符串文本视为九字节数组,{0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64,0x00}。调用strlen时,它将计算字节数,直到遇到第一个0x00。strlen(“Password”)将返回8,即使从技术上讲,字符数组中有9个字符

因此,当您声明一个包含8个字节的数组时,如下所示,没有尾随的空字节:

BYTE HMAC[] = {0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64};
问题是,“strlen(HMAC)”将至少计数8个字节,并在遍历未定义内存时继续计数,直到它最终(如果有的话)到达一个为零的字节。充其量,您可能会很幸运,因为堆栈内存总是有一个零字节填充您的数组声明。它返回的值更有可能远大于8。也许它会崩溃

因此,当您解析协议包中的HMAC和MESSAGE字段时,您计算实际解析的字节数(不包括终止null)。并将该计数传递到hmac函数中,以指示数据的大小


我不知道您的协议代码,但我希望您没有使用strlen来解析数据包,以找出数据包中字符串的结尾。一个聪明的攻击者可以注入一个没有空终止符的数据包,并导致您的代码做坏事。我希望您正在安全仔细地解析。典型的协议代码不包括包装在里面的字符串中的空终止字节。通常,“长度”编码为整数字段,后跟字符串字节。使解析和确定长度是否超过读入的数据包大小变得更容易。

int a_len=9;int b_len=a HMAC_Init_ex(&ctx,HMAC,a_len,EVP_sha1(),NULL);HMAC_更新(&ctx,数据2,b_len)这会更好?a_len=8;b_len=7(因为“密码”的长度为8个字符,“消息”的长度为7个字符)。
BYTE HMAC[] = {0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64};