使用EC_KEY时EVP_PKEY_verify不起作用

时间:2019-07-13 12:02:43

标签: c openssl cryptography

EVP_PKEY_verify()在大多数情况下会在EVP_PKEY结构包含EC密钥时失败,但在某些情况下会成功。

关于EVP_PKEY_verify()

openssl文档仅显示带有rsa键的示例。但是当EVP_PKEY包含EC密钥时,我找不到任何验证示例

    auto evp = EVP_PKEY_new();
    auto eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    assert(1 == EC_KEY_generate_key(eckey));
    assert(1 == EC_KEY_check_key(eckey));
    assert(1 == EVP_PKEY_assign_EC_KEY(evp, eckey));

    vector<unsigned char> msg = { 'a', 'd', 'f', 'h', 'k' };

    const int sha256Len = 32;
    unsigned char sha[sha256Len];

    SHA256(&(msg[0]), msg.size(), sha);

    //----signing
    auto evpctx=EVP_PKEY_CTX_new(evp, nullptr);

    assert(1 == EVP_PKEY_sign_init(evpctx));

    assert(1 == EVP_PKEY_CTX_set_signature_md(evpctx, EVP_sha256()));

    size_t signLen = 0;
    assert(1 == EVP_PKEY_sign(evpctx, NULL, &signLen, sha, sha256Len));

    vector<unsigned char> sig(signLen);

    auto ret = EVP_PKEY_sign(evpctx, &(sig[0]), &signLen, sha, sha256Len);

    assert(ret == 1);

    EVP_PKEY_CTX_free(evpctx);

    ///-----veryfication

    auto evpctx1 = EVP_PKEY_CTX_new(evp, nullptr);

    assert(1 == EVP_PKEY_verify_init(evpctx1));

    assert(1 == EVP_PKEY_CTX_set_signature_md(evpctx1, EVP_sha256()));

    ret = EVP_PKEY_verify(evpctx1, &sig[0], sig.size(), sha, sha256Len);

    EVP_PKEY_free(evp);
    EVP_PKEY_CTX_free(evpctx1);
    assert(ret == 1);

以上代码在循环中运行时,大多数情况下会失败,但并非总是如此。一些迭代成功。 如果我生成一个RSA密钥而不是EC密钥并将其放入EVP_PKEY,则可以。我做错了什么? 您能给我一个结合使用EVP_PKEY_verify()和ec键的工作示例吗?

1 个答案:

答案 0 :(得分:3)

问题如下:

在这里,您确定签名输出缓冲区的最大大小:

assert(1 == EVP_PKEY_sign(evpctx, NULL, &signLen, sha, sha256Len));

在这里分配此缓冲区:

vector<unsigned char> sig(signLen);

这是正确的。但是您必须知道,这只是最大所需的大小。确实是使用的大小可以小于

所以在这一行

auto ret = EVP_PKEY_sign(evpctx, &(sig[0]), &signLen, sha, sha256Len);

实际上 个已使用的输出缓冲区大小将写入signLen,您必须在此处指定

ret = EVP_PKEY_verify(evpctx1, &sig[0], signLen, sha, sha256Len);

当您验证签名时!经过小的修改,您的代码应该可以按预期工作。