C ++ OpenSSL HMACSHA1工作但不是我想要的

时间:2011-09-29 02:53:13

标签: c++ visual-c++ packet-capture hmac hmacsha1

以下HMACSHA1代码适用于将“密码”和“消息”转换为AFF791FA574D564C83F6456CC198CBD316949DC9作为http://buchananweb.co.uk/security01.aspx的证据。

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

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。但是,我的问题更多的是将其从数据中删除,并使用它...它还可以吗?

1 个答案:

答案 0 :(得分:2)

问题是数组,字符串和null char之间的关系。

当您声明“密码”时,编译器在逻辑上将字符串文字视为九字节数组{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字段时,您会计算实际解析的字节数(不包括终止空值)。并将该计数传递给hmac函数以指示数据的大小。

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