使用 RAW EC 生成的密钥在 C 中进行 OpenSSL 签名和验证
OpenSSL Sign and Verify in C with RAW EC generated Keys
我生成我的 EC 私钥作为随机数,我的 EC public 密钥作为随机数生成器的乘积。
现在我想用这些密钥对消息进行签名和验证,但是验证操作失败了。你有什么解决这个问题的提示吗?
我使用 OpenSSL 1.0.0 来解决一些限制。换不了新的
#include <openssl/ec.h>
#include <openssl/rand.h>
#include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>
int main()
{
BN_CTX *ctx;
EC_GROUP *curve;
BIGNUM *q = NULL;
EVP_MD_CTX *hashctx;
unsigned int ol;
unsigned char fh[EVP_MAX_MD_SIZE];
BIGNUM *priv = NULL;
EC_POINT *G, *pub;
EC_KEY *keypriv = EC_KEY_new();
EC_KEY *keypub = EC_KEY_new();
unsigned char *s1 = "hello";
// makes all algorithms available to the EVP* routines
OpenSSL_add_all_algorithms();
// load the error strings for ERR_error_string
ERR_load_crypto_strings();
hashctx = EVP_MD_CTX_new();
const EVP_MD *hashptr = EVP_get_digestbyname("SHA256");
EVP_DigestInit_ex(hashctx, hashptr, NULL);
EVP_DigestUpdate(hashctx, s1, strlen(s1));
EVP_DigestFinal_ex(hashctx, fh, &ol);
// seed PRNG
if (RAND_load_file("/dev/urandom", 256) < 64)
{
printf("Can't seed PRNG!\n");
abort();
}
ctx = BN_CTX_new();
q = BN_new();
// read the generator and order of the curve
curve = EC_GROUP_new_by_curve_name(NID_secp160r1);
G = EC_GROUP_get0_generator(curve);
EC_GROUP_get_order(curve, q, ctx);
// precompute multiples of g (faster multiplications)
EC_GROUP_precompute_mult(curve, ctx);
EC_KEY_set_group(keypriv, curve);
pub = EC_POINT_new(curve);
priv = BN_new();
BN_rand_range(priv, q);
EC_POINT_mul(curve, pub, NULL, G, priv, ctx);
EC_KEY_set_private_key(keypriv, priv);
EC_KEY_set_public_key(keypub, pub);
ECDSA_SIG *signature = ECDSA_do_sign(fh, 64, keypriv);
if (NULL == signature)
{
printf("Failed to generate EC Signature\n");
}
else
{
int verify_status = ECDSA_do_verify(fh, 64, signature, keypub);
const int verify_success = 1;
if (verify_success != verify_status)
{
printf("Failed to verify EC Signature\n");
}
else
{
printf("Verifed EC Signature\n");
}
ECDSA_SIG_free(signature);
}
return 0;
}
我通过在我的代码中为 public 键设置 EC 组解决了这个问题:
EC_KEY_set_group(keypub, curve);
顺便说一下,我希望这个 Q/A 也可以回答已接受答案中的第一条评论:
How do you verify with just the public part of the eckey?
Signing a message using ECDSA in OpenSSL
我生成我的 EC 私钥作为随机数,我的 EC public 密钥作为随机数生成器的乘积。
现在我想用这些密钥对消息进行签名和验证,但是验证操作失败了。你有什么解决这个问题的提示吗?
我使用 OpenSSL 1.0.0 来解决一些限制。换不了新的
#include <openssl/ec.h>
#include <openssl/rand.h>
#include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>
int main()
{
BN_CTX *ctx;
EC_GROUP *curve;
BIGNUM *q = NULL;
EVP_MD_CTX *hashctx;
unsigned int ol;
unsigned char fh[EVP_MAX_MD_SIZE];
BIGNUM *priv = NULL;
EC_POINT *G, *pub;
EC_KEY *keypriv = EC_KEY_new();
EC_KEY *keypub = EC_KEY_new();
unsigned char *s1 = "hello";
// makes all algorithms available to the EVP* routines
OpenSSL_add_all_algorithms();
// load the error strings for ERR_error_string
ERR_load_crypto_strings();
hashctx = EVP_MD_CTX_new();
const EVP_MD *hashptr = EVP_get_digestbyname("SHA256");
EVP_DigestInit_ex(hashctx, hashptr, NULL);
EVP_DigestUpdate(hashctx, s1, strlen(s1));
EVP_DigestFinal_ex(hashctx, fh, &ol);
// seed PRNG
if (RAND_load_file("/dev/urandom", 256) < 64)
{
printf("Can't seed PRNG!\n");
abort();
}
ctx = BN_CTX_new();
q = BN_new();
// read the generator and order of the curve
curve = EC_GROUP_new_by_curve_name(NID_secp160r1);
G = EC_GROUP_get0_generator(curve);
EC_GROUP_get_order(curve, q, ctx);
// precompute multiples of g (faster multiplications)
EC_GROUP_precompute_mult(curve, ctx);
EC_KEY_set_group(keypriv, curve);
pub = EC_POINT_new(curve);
priv = BN_new();
BN_rand_range(priv, q);
EC_POINT_mul(curve, pub, NULL, G, priv, ctx);
EC_KEY_set_private_key(keypriv, priv);
EC_KEY_set_public_key(keypub, pub);
ECDSA_SIG *signature = ECDSA_do_sign(fh, 64, keypriv);
if (NULL == signature)
{
printf("Failed to generate EC Signature\n");
}
else
{
int verify_status = ECDSA_do_verify(fh, 64, signature, keypub);
const int verify_success = 1;
if (verify_success != verify_status)
{
printf("Failed to verify EC Signature\n");
}
else
{
printf("Verifed EC Signature\n");
}
ECDSA_SIG_free(signature);
}
return 0;
}
我通过在我的代码中为 public 键设置 EC 组解决了这个问题:
EC_KEY_set_group(keypub, curve);
顺便说一下,我希望这个 Q/A 也可以回答已接受答案中的第一条评论:
How do you verify with just the public part of the eckey?
Signing a message using ECDSA in OpenSSL