C++ OpenSSL HMACSHA1 可以工作,但不是我想要的那样

发布于 2024-12-07 06:24:54 字数 1804 浏览 0 评论 0原文

下面的 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

我会 rip 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。但是,我的问题更多的是从数据中剥离它并使用它......它仍然可以吗?

This HMACSHA1 code below works for converting "Password" and "Message" to AFF791FA574D564C83F6456CC198CBD316949DC9 as evidence by http://buchananweb.co.uk/security01.aspx.

My question is, Is it possible to have:

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

And still get the same value: AFF791FA574D564C83F6456CC198CBD316949DC9.

For example, if I was on a server and received the packet:

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

And I rip 50 61 73 73 77 6F 72 64 & 4D 65 73 73 61 67 65 from the packet and used this for my HMACSHA1. How would I go about doing that to get the correct HMACSHA1 value?

    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

EDIT:

It works by doing this:

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

By adding 0x00, at the end. But, my question is more towards ripping it from data, and using it... would it still be fine?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如若梦似彩虹 2024-12-14 06:24:54

问题在于数组、字符串和空字符之间的关系。

当您声明“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 来解析数据包来找出数据包内字符串的结束位置。聪明的攻击者可能会注入没有空终止符的数据包,并导致您的代码做坏事。我希望您能够安全、仔细地解析。典型的协议代码不包括内部字符串中的空终止字节。通常,“长度”被编码为整数字段,后跟字符串字节。更容易解析和确定长度是否超过读入的数据包大小。

The issue is the relation ship between arrays, strings, and the null char.

When you declare "Password", the compiler logically treats the string literal as a nine byte array, {0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64, 0x00}. When you call strlen, it will count the number of bytes until it encounters the first 0x00. strlen("Password") will return 8 even though there are technically nine characters in the array of characters.

So when you declare an array of 8 bytes as follows without a trailing null byte:

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

The problem is that "strlen(HMAC)" will count at least 8 bytes, and keep counting while traversing undefined memory until it finally (if ever) hits a byte that is zero. At best, you might get lucky because the stack memory always has a zero byte padding your array declaration. More likely it will return a value much larger than 8. Maybe it will crash.

So when you parse the HMAC and MESSAGE field from your protocol packet, you count the number of bytes actually parsed (not including the terminating null). And pass that count into the hmac functions to indicate the size of your data.

I don't know your protocol code, but I hope you aren't using strlen to parse the packet to figure out where the string inside the packet ends. A clever attacker could inject a packet with no null terminator and cause your code do bad things. I hope you are parsing securely and carefully. Typical protocol code doesn't include the null terminating byte in the strings packed inside. Usually the "length" is encoded as an integer field followed by the string bytes. Makes it easier to parse and determine if the length would exceed the packet size read in.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文