Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何通过原生字符串秘钥生成EVP_PKEY结构? #3

Open
ccjinghang opened this issue Nov 19, 2019 · 1 comment
Open

如何通过原生字符串秘钥生成EVP_PKEY结构? #3

ccjinghang opened this issue Nov 19, 2019 · 1 comment

Comments

@ccjinghang
Copy link

ccjinghang commented Nov 19, 2019

@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

@tan00
Copy link
Owner

tan00 commented Nov 29, 2019

java bc生成的密钥比openssl的多出一个object id, 去掉即可.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants