您好,我正在尝试使用OpenSSL(evp)生成一对私钥和公钥,但是我的代码遇到很多问题,如下所示:
EVP_PKEY_CTX *ctx = NULL;
if(!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, NID_secp256k1))
{
std::cout << "error 1 " << std::endl;
}
else
{
EVP_PKEY *pkey = NULL;
ENGINE *e = NULL;
if(*pkey != NULL)
{
if(!(ctx = EVP_PKEY_CTX_new(pkey, e)))
{
std::cout << "bien 1" << std::endl;
}
}
else
{
int id{0};
id++;
if(!(ctx = EVP_PKEY_CTX_new_id(id, e)))
{
std::cout << "bien 2" << std::endl;
}
}
EVP_PKEY *ppkey = NULL;
if (1 != EVP_PKEY_keygen(ctx, &ppkey))
{
std::cout << "error 2" << std::endl;
}
else
{
std::cout << *ppkey << std::endl;
}
}
密钥通常应该在
ppkey
中,但是我无法访问其内容。这是出现的错误:
main.cpp | 20 |错误:'operator!='不匹配(操作数类型为'EVP_PKEY'{aka'evp_pkey_st'}和'long long int')|
最佳答案
根据EVP_PKEY_keygen() man page EVP_PKEY_keygen()
功能界面是
int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
您可以通过
ppkey
参数的地址来调用此API;EVP_PKEY **ppkey;
if (! EVP_PKEY_keygen (ctx, &ppkey))
{
}
由于其类型为
EVP_PKEY **
,因此实际上您正在向函数传递EVP_PKEY ***
参数,这会导致您遇到错误。试试看
EVP_PKEY **ppkey;
if (! EVP_PKEY_keygen (ctx, ppkey))
{
}
甚至更好
EVP_PKEY *ppkey;
if (! EVP_PKEY_keygen (ctx, &ppkey))
{
}
这样,您的指针将包含所需键结构的地址。
EVP_PKEY_keygen()函数执行密钥生成操作,
生成的密钥被写入ppkey。
然后,您将能够像在C中的每个struct字段一样访问其字段。例如,在
EVP_PKEY *ppkey;
的情况下,您将具有ppkey->ameth
(访问结构指针的字段)或(*ppkey).ameth
(直接访问以下字段)递归指针后的结构)。仅出于完整性考虑,这是
EVP_PKEY
结构的定义(git版本_OpenSSL_1_1_1-2526-gdc8de3e_):从include / openssl / types.h中:
typedef struct evp_pkey_st EVP_PKEY;
从include / crypto / evp.h:
/*
* Type needs to be a bit field Sub-type needs to be for variations on the
* method, as in, can it do arbitrary encryption....
*/
struct evp_pkey_st {
/* == Legacy attributes == */
int type;
int save_type;
const EVP_PKEY_ASN1_METHOD *ameth;
ENGINE *engine;
ENGINE *pmeth_engine; /* If not NULL public key ENGINE to use */
union {
void *ptr;
# ifndef OPENSSL_NO_RSA
struct rsa_st *rsa; /* RSA */
# endif
# ifndef OPENSSL_NO_DSA
struct dsa_st *dsa; /* DSA */
# endif
# ifndef OPENSSL_NO_DH
struct dh_st *dh; /* DH */
# endif
# ifndef OPENSSL_NO_EC
struct ec_key_st *ec; /* ECC */
ECX_KEY *ecx; /* X25519, X448, Ed25519, Ed448 */
# endif
} pkey;
/* == Common attributes == */
CRYPTO_REF_COUNT references;
CRYPTO_RWLOCK *lock;
STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
int save_parameters;
/* == Provider attributes == */
/*
* To support transparent export/import between providers that
* support the methods for it, and still not having to do the
* export/import every time a key or domain params are used, we
* maintain a cache of imported key / domain params, indexed by
* provider address. pkeys[0] is *always* the "original" data.
*/
struct {
EVP_KEYMGMT *keymgmt;
void *provdata;
/* 0 = provdata is a key, 1 = provdata is domain params */
int domainparams;
} pkeys[10];
/*
* If there is a legacy key assigned to this structure, we keep
* a copy of that key's dirty count.
*/
size_t dirty_cnt_copy;
/* Cache of domain parameter / key information */
struct {
int bits;
int security_bits;
int size;
} cache;
} /* EVP_PKEY */ ;