【问题标题】:OpenSSL Sign and Verify in C with RAW EC generated Keys使用原始 EC 生成的密钥在 C 中进行 OpenSSL 签名和验证
【发布时间】:2020-09-29 16:15:27
【问题描述】:

我将我的 EC 私钥生成为随机数,并将我的 EC 公钥生成为随机数生成器的乘积。

现在我想使用这些密钥来签署和验证一条消息,但是关于验证的操作失败了。你有什么提示可以解决这个问题吗?

我使用 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;
}

【问题讨论】:

    标签: c openssl cryptography public-key-encryption


    【解决方案1】:

    我只是通过在我的代码中将公钥设置为 EC 组来解决:

    EC_KEY_set_group(keypub, curve);
    

    顺便说一句,我希望这个 Q/A 也可以回答已接受答案中的第一条评论:

    如何仅使用 eckey 的公共部分进行验证?

    Signing a message using ECDSA in OpenSSL

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-22
      • 1970-01-01
      • 2022-12-04
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      相关资源
      最近更新 更多