2011-09-29 40 views
0

下面的这个HMACSHA1代码适用于将“密码”和“消息”转换为AFF791FA574D564C83F6456CC198CBD316949DC9,作为http://buchananweb.co.uk/security01.aspx的证据。C++ OpenSSL HMACSHA1的工作原理但不是我想要的方式

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

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,在最后。但是,我的问题更多的是将它从数据中剥离出来,然后使用它......它会一直很好吗?

回答

2

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

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

所以当声明的8个字节数组作为末尾没有空字节如下:

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

的问题是,“strlen的(HMAC)”将计数至少8个字节,并保持计数在遍历未定义的内存,直到它终于(如果有的话)命中一个零的字节。充其量,你可能会很幸运,因为堆栈内存总是有一个填充数组声明的零字节。更有可能它会返回比8更大的值。也许它会崩溃。

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

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

+0

'int a_len = 9; int b_len = a HMAC_Init_ex(&ctx,HMAC,a_len,EVP_sha1(),NULL); HMAC_Update(&ctx,data2,b_len);' 这会更好吗? – user954753

+0

a_len = 8; b_len = 7(因为“密码”的长度是8个字符,而“消息”是7个字符)。 – selbie

+0

谢谢,我会这样做:-) – user954753

相关问题