2

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);

这里,显示我的库运行时 40%用于在幕后创建和删除 HMAC_CTX 。

还有两个附加函数可以显式地创建和销毁HMAC_CTX

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

HMAC_CTX_cleanup() 从 HMAC_CTX 中擦除密钥和其他数据并释放任何相关资源。当不再需要 HMAC_CTX 时必须调用它。

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

如果消息没有完全存储在内存中,可以使用以下函数

我的数据完全适合内存,所以我选择了 HMAC 函数——其签名如上所示。

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

HMAC_Update() 可以使用要验证的消息块(数据中的 len 个字节)重复调用。

HMAC_Final() 将消息验证码放在 md 中,md 中必须有空间用于散列函数输出。


适用范围

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

上面的描述应该阐明库需要是线程安全的,并且可能具有可恢复的处理状态——即,共享操作系统线程的轻量级线程(这可能会使线程本地内存不可用)。


问题

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

(1) 可能可以使用线程本地内存来完成——但我如何重用 CTX 的?HMAC_final ()调用是否使 CTX 可重用?

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

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

伪代码和评论将很有用。

4

2 回答 2

2

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

HMAC_Init_ex()初始化或重用结构以 HMAC_CTX使用 function evp_md和 key key。两者都可以 NULL,在这种情况下,现有的将被重用。

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

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

于 2010-04-13T05:31:55.580 回答
0

如果您不想限制您的依赖关系,您可以选择一个自包含的 HMAC 实现,并要求用户明确控制 OpenSSL 在其文档中模糊不清的所有方面。存在许多此类简单的 C/C++ 替代方案,但您可以选择和评估此类替代方案。

于 2010-04-12T11:08:18.147 回答