c - 使用 EC_KEY 时 EVP_PKEY_verify 不起作用
问题描述
EVP_PKEY_verify()
如果 EVP_PKEY 结构包含 EC 密钥,在大多数情况下会失败,但在某些情况下会成功。
openssl 文档EVP_PKEY_verify()
仅显示带有 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 密钥的工作示例吗?
解决方案
问题如下:
在这里,您确定签名输出缓冲区的最大大小:
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);
当您验证签名时!通过这个小修改,您的代码应该可以按预期工作。
推荐阅读
- javascript - 如何从 AngularJS 调用 PHP 文件
- laravel - 在laravel中注册用户时如何将用户ID和角色ID保存在用户角色表中?
- ngrx - 如何在ngrx效果中操作数据并将其作为有效负载返回到操作?
- mysql - 如何避免基于数据库中陈旧数据的最终用户操作
- azure-sql-managed-instance - 如何在 Azure SQL 托管实例上查找数据库的最早还原点
- python - TeamCity - 根据先前调用脚本的返回值在构建步骤中设置参数
- python - 使用自定义索引重新分区 Dask Dataframe
- c++ - 将指针作为参数传递给函数
- button - Pluguins.Forms.Button.Circle 点击问题
- .net - 如何让 Visual Studio O/R Designer 自动生成继承对象的集合?