使用OpenSSL对类型'struct ec_key_st'的错误定义不完整

mia*_*ray 2 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));
                              ~~~~~^
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码有什么问题?如果我删除了printf行,则可以正常工作。如果有人帮助我摆脱此错误,我将不胜感激。

bar*_*njs 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));
Run Code Online (Sandbox Code Playgroud)

会成为

{
    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);
}
Run Code Online (Sandbox Code Playgroud)

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


hut*_*ano 0

您需要从 openssl 库获取“ec_lcl.h”头文件,以便访问结构体“ec_key_st”的成员。请注意,“ECKEY”定义为:

typedef struct ec_key_st EC_KEY;
Run Code Online (Sandbox Code Playgroud)

因此,您将“ec_lcl.h”放入项目文件夹中,然后将代码更改为:

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • 当然,您可以自由地使用开源库做任何您喜欢的事情。但一旦你打开内部的盖子,你就会碰到一整罐蠕虫。您被绑定到库的特定补丁级别,因此您的代码可能变得非常脆弱。这在安全库中尤其危险。我对“正确”这个词的使用应该理解为“它被设计的使用方式”。 (3认同)
  • 难道真的是“不正确的方式”吗?技术上“不正确”?社交上?为什么?因为其他一些强迫症患者的感情可能会受到伤害?OpenSSL 是开源库。因此,如果有些人可以阅读并理解其内部结构,他们就应该有权随心所欲地使用它们,至少只要他们不期望自己的代码能够适应该库的未来更改。 (2认同)