使用OpenSSL错误地未定义“struct ec_key_st”类型

时间:2017-10-03 13:49:53

标签: c openssl ecdsa

我正在尝试通过openssl从给定的秘密计算公钥。我收到这个错误:

main.c:27: error: incomplete definition of type 'struct ec_key_st'
  printf("d: %s\n", BN_bn2hex(eckey->priv_key));
                              ~~~~~^

这是我的代码:

#include <stdio.h>

#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/bn.h>
#include <openssl/obj_mac.h>

int main()
{
  BN_CTX *ctx = BN_CTX_new();

  EC_KEY *eckey = EC_KEY_new();
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp256k1);
  EC_KEY_set_group(eckey, group);

  BIGNUM *prv = BN_new();
  BN_hex2bn(&prv, "b14fac12b3fa7dd6f2562a18d554fcd6818137ebb7e0d119ab0776d6407664f9");
  EC_KEY_set_private_key(eckey, prv);

  EC_POINT *Q = EC_POINT_new(group);
  EC_POINT_mul(group, Q, prv, NULL, NULL, ctx);
  EC_KEY_set_public_key(eckey, Q);

  if (EC_KEY_check_key(eckey))
    printf("Key succesfully checked.\n");

  printf("d: %s\n", BN_bn2hex(eckey->priv_key));
  printf("X: %s\n", BN_bn2hex(&eckey->pub_key->X));
  printf("Y: %s\n", BN_bn2hex(&eckey->pub_key->Y));

  EC_GROUP_free (group); group = NULL;
  EC_KEY_free (eckey); eckey = NULL;
  return 0;
}

上述代码有什么问题?如果我删除printf行,它工作正常。如果有人帮助我摆脱这个错误,我将不胜感激。

2 个答案:

答案 0 :(得分:5)

你正在使用OpenSSL 1.1,他们已经决定你不应该再去探索他们结构的内部了。

eckey->priv_key是在OpenSSL 1.0.x中访问私钥的有效方式,但现在唯一正确的方法是EC_KEY_get0_private_key(eckey)

同样,对于公钥,它是EC_KEY_get0_public_key(eckey)

这两个函数都是在OpenSSL 1.0.x期间声明的,因此您可以将代码编写为相同的代码。

所以

printf("d: %s\n", BN_bn2hex(eckey->priv_key));
printf("X: %s\n", BN_bn2hex(&eckey->pub_key->X));
printf("Y: %s\n", BN_bn2hex(&eckey->pub_key->Y));

会变成

{
    const BIGNUM* d = EC_KEY_get0_private_key(eckey);
    const EC_POINT* Q = EC_KEY_get0_public_key(eckey);
    const EC_GROUP* group = EC_KEY_get0_group(eckey);
    BIGNUM* x = BN_new();
    BIGNUM* y = BN_new();

    if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, null))
    {
        error();
    }

    printf("d: %s\n", BN_bn2hex(d));
    printf("X: %s\n", BN_bn2hex(x));
    printf("Y: %s\n", BN_bn2hex(y));

    BN_free(x);
    BN_free(y);
}

这使代码保持正常工作,即使OpenSSL 1.1.1决定重做隐藏在ec_lcl.h中的结构布局

答案 1 :(得分:0)

你需要得到&#34; ec_lcl.h&#34;来自openssl libarary的头文件,以便访问struct&#34; ec_key_st&#34;的成员。请注意&#34; ECKEY&#34;定义为:

typedef struct ec_key_st EC_KEY;

所以你把&#34; ec_lcl.h&#34;在您的项目文件夹中,然后将您的代码更改为:

#include <stdio.h>

#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/bn.h>
#include <openssl/obj_mac.h>

#include "ec_lcl.h"

int main()
{
  BN_CTX *ctx = BN_CTX_new();

  struct ec_key_st *eckey = EC_KEY_new();
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp256k1);
  EC_KEY_set_group(eckey, group);

  BIGNUM *prv = BN_new();
  BN_hex2bn(&prv, "b14fac12b3fa7dd6f2562a18d554fcd6818137ebb7e0d119ab0776d6407664f9");
  EC_KEY_set_private_key(eckey, prv);

  EC_POINT *Q = EC_POINT_new(group);
  EC_POINT_mul(group, Q, prv, NULL, NULL, ctx);
  EC_KEY_set_public_key(eckey, Q);

  if (EC_KEY_check_key(eckey))
    printf("Key succesfully checked.\n");

  printf("d: %s\n", BN_bn2hex(eckey->priv_key));
  printf("X: %s\n", BN_bn2hex(&eckey->pub_key->X));
  printf("Y: %s\n", BN_bn2hex(&eckey->pub_key->Y));

  EC_GROUP_free (group); group = NULL;
  EC_KEY_free (eckey); eckey = NULL;
  return 0;
}