-
Notifications
You must be signed in to change notification settings - Fork 8
Description
@tan00 您好!
请教个问题,如何通过原生字符串秘钥生成EVP_PKEY结构?
我的方式如下:
EVP_PKEY* covert_string_evp_pkey_new(unsigned char* buf,int is_public)
{
if (NULL == buf)
{
return NULL;
}
EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_sm2p256v1);
long keylen=0;
unsigned char *key = NULL;
if (!(key = OPENSSL_hexstr2buf((char *)buf, &keylen)))
{
return NULL;
}
/*
if (keylen != 32 )
{
printf("__LINE__=%ld\n",__LINE__);
// OPENSSL_cleanse(key, keylen);
}*/
if(is_public)
{
if(!EC_KEY_oct2key(eckey,key, keylen,NULL))
{
OPENSSL_cleanse(key, keylen);
}
}
else
{
if (!EC_KEY_oct2priv(eckey, key, keylen))
{
OPENSSL_cleanse(key, keylen);
}
}
OPENSSL_cleanse(key, keylen);
EVP_PKEY *evp_key = EVP_PKEY_new();
if(!EVP_PKEY_set1_EC_KEY(evp_key,eckey))
{
OPENSSL_cleanse(key, keylen);
return NULL;
}
return evp_key;
}
采用这种方式确实可以生成EVP_PKEY,且我内部加验签也可以成功,加验签如下:
struct AlgorithmParams
{
const unsigned char *public_key;
const unsigned char *private_key;
int pri_key_len;
int pub_key_len;
const unsigned char *str_in;
int str_in_len;
unsigned char *str_out;
int str_out_len;
const unsigned char *iv;
int pendding; //0 不填充 默认填充
};
int sm2_sign(struct AlgorithmParams *param)
{
if(NULL == param)
{
fprintf(stderr, "%s() failed to sm2_sign\n", func);
return -1;
}
char szErr[1024];
int nRet = 0;
int value = 0;
EVP_PKEY *pkey = NULL;
const EVP_MD *md = NULL;
EVP_MD_CTX *mdctx = NULL;
if(!(pkey = covert_string_evp_pkey_new(param->private_key,0)))
{
printf("LINE=%d\n",LINE);
return -1;
}
md = EVP_sm3();
if(!(mdctx=EVP_MD_CTX_new()))
{
fprintf(stderr, "%s() failed to call EVP_MD_CTX_new\n", __func__);
nRet = -1;
goto sign_ret;
}
if(!EVP_DigestSignInit(mdctx, NULL,md, NULL,pkey))
{
value = ERR_get_error();
ERR_error_string( value, szErr );
fprintf( stderr,"OpenSSL_Sign: EVP_SignUpdate failed: \nopenssl return %d, %s\n", value, szErr );
nRet = -1;
goto sign_ret;
}
if(!EVP_DigestSignUpdate(mdctx, param->str_in, param->str_in_len))
{
value = ERR_get_error();
ERR_error_string( value, szErr );
fprintf( stderr,"OpenSSL_Sign: EVP_SignUpdate failed: \nopenssl return %d, %s\n", value, szErr );
nRet = -2;
goto sign_ret;
}
if(!EVP_DigestSignFinal(mdctx, param->str_out, &(param->str_out_len)))
{
value = ERR_get_error();
ERR_error_string( value, szErr );
fprintf( stderr,"OpenSSL_Sign: EVP_SignFinal failed: \nopenssl return %d, %s\n", value, szErr );
nRet = -3;
goto sign_ret;
}
sign_ret:
/if( !EVP_MD_CTX_cleanup(mdctx) ) {
value = ERR_get_error();
ERR_error_string( value, szErr );
fprintf( stderr,"OpenSSL_Sign: EVP_ctx_cleanup failed: \nopenssl return %d, %s\n", value, szErr );
}/
EVP_PKEY_free(pkey);
EVP_MD_CTX_destroy(mdctx);
return nRet;
}
int sm2_verify(struct AlgorithmParams *param)
{
if(NULL == param)
{
fprintf(stderr, "%s() failed to sm2_verify\n", func);
return -1;
}
char szErr[1024];
int nRet = 0;
int value = 0;
EVP_PKEY *pkey = NULL;
const EVP_MD *md = NULL;
EVP_MD_CTX *mdctx = NULL;
if(! (pkey = covert_string_evp_pkey_new(param->public_key,1)))
{
return -1;
}
md = EVP_sm3();
if(!(mdctx=EVP_MD_CTX_new()))
{
fprintf(stderr, "%s() failed to call EVP_MD_CTX_new\n", __func__);
nRet = -1;
goto verify_ret;
}
if(!EVP_DigestVerifyInit(mdctx, NULL,md, NULL,pkey))
{
value = ERR_get_error();
ERR_error_string( value, szErr );
fprintf( stderr,"OpenSSL_Sign: EVP_DigestVerifyInit failed: \nopenssl return %d, %s\n", value, szErr );
nRet = -1;
goto verify_ret;
}
if(!EVP_DigestVerifyUpdate(mdctx, param->str_in, param->str_in_len))
{
value = ERR_get_error();
ERR_error_string( value, szErr );
fprintf( stderr,"OpenSSL_Sign: EVP_DigestVerifyUpdate failed: \nopenssl return %d, %s\n", value, szErr );
nRet = -2;
goto verify_ret;
}
if(!EVP_DigestVerifyFinal(mdctx, param->str_out, param->str_out_len))
{
value = ERR_get_error();
ERR_error_string( value, szErr );
fprintf( stderr,"OpenSSL_Sign: EVP_DigestVerifyFinal failed: \nopenssl return %d, %s\n", value, szErr );
nRet = -3;
goto verify_ret;
}
verify_ret:
/if( !EVP_MD_CTX_cleanup(mdctx) ) {
value = ERR_get_error();
ERR_error_string( value, szErr );
fprintf( stderr,"OpenSSL_Sign: EVP_ctx_cleanup failed: \nopenssl return %d, %s\n", value, szErr );
}/
EVP_PKEY_free(pkey);
EVP_MD_CTX_destroy(mdctx);
return nRet;
}
确实可以加验签成功,但是,采用java bc加签的签名,我这边无法验签成功,反之亦然。是sm2的参数设置有误还是?请指教!
验证java bc的签名报错结果如下:
openssl return 269181073, error:100B6091:elliptic curve routines:ec_GFp_simple_oct2point:invalid encoding