OpenSSL HMAC功能中的意外复杂性

时间:2010-04-12 10:54:33

标签: c++ profiling thread-safety openssl hmac

SSL文档分析

这个问题与OpenSSL中HMAC例程的使用有关。

由于Openssl文档在某些方面有点偏弱,因此分析显示使用:

 unsigned char *HMAC(const EVP_MD *evp_md, const void *key,
               int key_len, const unsigned char *d, int n,
               unsigned char *md, unsigned int *md_len);

here开始, 40%的图书馆运行时用于在幕后创建和删除 HMAC_CTX

另外还有两个功能可以明确地创建和销毁 HMAC_CTX

  

HMAC_CTX_init()初始化HMAC_CTX   在第一次使用之前它必须被调用。

     

HMAC_CTX_cleanup()删除密钥和   HMAC_CTX和其他数据   释放任何相关资源。它   必须在HMAC_CTX为no时调用   需要更长时间。

这两个函数调用的前缀为:

  

如果,可以使用以下功能   消息未完全存储   在记忆中

我的数据完全适合内存,因此我选择HMAC功能 - 上面显示其签名的功能。

如手册页所述,上下文通过使用以下两个函数来使用:

  

可以重复调用HMAC_Update()   用大块的消息来做   经过身份验证(数据中的len个字节)。

     

HMAC_Final()放置消息   md中的身份验证代码,必须   有散列函数的空间   输出


申请范围

我的应用程序生成一个真实的(HMAC,也使用nonce),CBC-BF加密协议缓冲区字符串。代码将与各种Web服务器和框架Windows / Linux作为OS,nginx,Apache和IIS作为Web服务器和Python / .NET和C ++ Web服务器过滤器连接。

上面的描述应该说明库需要是线程安全的,并且可能具有可恢复的处理状态 - 即,轻量级线程共享OS线程(这可能会使线程本地内存脱离图片)。


问题

如何以(1)线程安全/(2)可恢复状态方式摆脱每次调用 40%的开销? (2)是可选的,因为我将所有源数据一次性存在,并且可以确保在不放弃对线程中间摘要创建的控制的情况下创建摘要。所以,

(1)可以使用线程本地内存来完成 - 但是如何重新使用CTX呢? HMAC_final()调用是否使CTX可重用?

(2)可选:在这种情况下,我必须创建一个CTX池。

(3)HMAC功能如何做到这一点?它会在函数调用的范围内创建一个CTX并将其销毁吗?

Psuedocode和评论将非常有用。

2 个答案:

答案 0 :(得分:2)

OpenSSL 0.9.8g中HMAC_Init_ex()函数的文档说:

  

HMAC_Init_ex()初始化或重新使用 a   HMAC_CTX结构使用该函数   evp_md和密钥key。要么可以   NULL,在这种情况下是现有的   将被重复使用。

(强调我的)。这意味着您可以使用HMAC_CTX初始化HMAC_CTX_Init()一次,然后保留它以创建多个HMAC,只要您不在其上调用HMAC_CTX_cleanup()并开始每个HMAC都有HMAC_Init_ex()

所以是的,你应该能够在线程本地内存中使用HMAC_CTX做你想做的事。

答案 1 :(得分:0)

如果您没有尝试限制您的依赖项,您可以选择自包含的HMAC实现,并要求用户明确控制OpenSSL的所有方面,在其文档中,模糊不清。存在许多这样简单的C / C ++替代方案,但是您可以选择并评估这样的替代方案。