【发布时间】:2015-03-22 23:59:23
【问题描述】:
我正在尝试在 Windows 上使用 OpenSSL 1.0.2a 生成 ECDHE 密钥,并具有以下示例代码:
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ecdh.h>
int main()
{
OpenSSL_add_all_algorithms(); ERR_load_crypto_strings();
EVP_PKEY_CTX* parameters_context = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
EVP_PKEY* cparameters = nullptr;
EVP_PKEY* private_key = nullptr;
if (EVP_PKEY_paramgen_init(parameters_context) != 1) { return 1; }
if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(parameters_context, NID_sect571k1) != 1) { return 1; }
if (EVP_PKEY_paramgen(parameters_context, &cparameters) != 1) { return 1; }
EVP_PKEY_CTX* key_generation_context = EVP_PKEY_CTX_new(cparameters, NULL);
if (!key_generation_context) { return 1; }
if (EVP_PKEY_keygen_init(key_generation_context) != 1) { return 1; }
if (EVP_PKEY_keygen(key_generation_context, &private_key) != 1) { return 1; }
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_PUBKEY(bio, private_key); // <== This is where things go wrong.
ERR_free_strings(); EVP_cleanup(); CRYPTO_cleanup_all_ex_data();
}
我在其他平台(OSX 和 Debian Linux,使用gcc)上测试了上述代码,它似乎工作正常(valgrind 下没有报告错误)。
当我在 Windows 上运行它时,它总是在这一行失败:
PEM_write_bio_PUBKEY(bio, private_key);
我得到了这个“不错”的错误屏幕:
我不知道出了什么问题:从我能找到的许多教程和文档页面来看,这似乎是正确的做事方式。
在我再花一天时间试图找出问题所在之前,我认为向社区提问可能会更明智:这是使用 OpenSSL 生成和写入 PEM 格式的 ECDHE 密钥的正确方法吗?
【问题讨论】:
-
这段代码在我看来没问题。您从哪里获得适用于 Windows 的 OpenSSL?你自己建的吗?如果是 Thomas Hruska 的 Win32 OpenSSL,您是否安装了所需的 C Runtime?
-
@jww 我自己构建的。我使用与示例代码相同的运行时和多线程链接设置。奇怪的是,我在我的项目中积极使用 OpenSSL,它对其他一切(RSA、GCM 模式下的 AES 加密、X509 证书生成等)都非常有效。真的只是 ECDHE 相关的操作看起来很崩溃。
-
在这种情况下,您可以考虑在未启用 ASM 的 Windows 上构建 OpenSSL。通过使用
no-asm进行配置来做到这一点。还有一个enable-ec_nistp_64_gcc_128选项会影响 ECDHE,但您可能没有使用它。如果您继续遇到崩溃,您可能会考虑提交一个错误(这就是我的意思)。 -
@jww 我在构建它时已经指定了
no-asm。如果这有什么不同,我正在构建一个静态库。感谢您对我的代码的反馈和确认:我想我别无选择,只能将该示例重构为更加独立的存档并提交错误。 -
为了记录,我在 OpenSSL 请求跟踪器上创建了a bug。
标签: c openssl elliptic-curve diffie-hellman