openssl 介绍(五) openssl rsa签名验签

直接签名

#include <string.h>
#include <openssl/objects.h>
#include <openssl/rsa.h>
int main(int argc, char const *argv[])
{
	int ret,j;
	RSA *r;
	int i,bits=1024,signlen,datalen,alg,nid;
	unsigned long e=RSA_3;
	BIGNUM *bne;
	unsigned char data[100],signret[200];
	bne=BN_new();
	ret=BN_set_word(bne,e);
	r=RSA_new();
	ret=RSA_generate_key_ex(r,bits,bne,NULL);
	if(ret!=1)
	{
		printf("RSA_generate_key_ex err!\n");
		return -1;
	}
	for(i=0;i<100;i++)
		memset(&data[i],i+1,1);
	printf("please select digest alg: \n");
	printf("1.NID_md5\n");
	printf("2.NID_sha\n");
	printf("3.NID_sha1\n");
	printf("4.NID_md5_sha1\n");
	scanf("%d",&alg);
	if(alg==1)
	{
		datalen=55;
		nid=NID_md5;
	}
	else if(alg==2)
	{
		datalen=55;
		nid=NID_sha;
	}
	else if(alg==3)
	{
		datalen=55;
		nid=NID_sha1;
	}
	else if(alg==4)
	{
		datalen=36;
		nid=NID_md5_sha1;
	}
	ret=RSA_sign(nid,data,datalen,signret,&signlen,r);
	for(j = 0; j < signlen; j++)
	{
		if(j%16==0)
			printf("\n%08xH: ",i);
		printf("%02x ", signret[j]);	
	}
	if(ret!=1)
	{
		printf("RSA_sign err!\n");
		RSA_free(r);
		return -1;
	}
	ret=RSA_verify(nid,data,datalen,signret,signlen,r);
	if(ret!=1)
	{
		printf("RSA_verify err!\n");
		RSA_free(r);
		return -1;
	}
	RSA_free(r);
	printf("test ok!\n");
	return 0;
}

摘要签名

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
 
void tSign()
{
	unsigned char sign_value[1024];	//保存签名值的数组
	int sign_len;			//签名值长度
	EVP_MD_CTX mdctx;		//摘要算法上下文变量
	char mess1[] = "xxh";		//待签名的消息
	RSA *rsa=NULL;			//RSA结构体变量
	EVP_PKEY *evpKey=NULL;		//EVP KEY结构体变量
	int i;
	
	printf("正在产生RSA密钥...");
	rsa = RSA_generate_key(1024,RSA_F4,NULL,NULL);//产生一个1024位的RSA密钥//printf ("bits: %d\n", BN_num_bits (rsa->n));//返回n的二进制位数!1024!
	if(rsa == NULL)
	{
		printf("gen rsa err\n");
		return;
	}
	printf(" 成功.\n");
	evpKey = EVP_PKEY_new();//新建一个EVP_PKEY变量
	if(evpKey == NULL)
	{
		printf("EVP_PKEY_new err\n");
		RSA_free(rsa);
		return ;
	}
	if(EVP_PKEY_set1_RSA(evpKey,rsa) != 1)	//保存RSA结构体到EVP_PKEY结构体
	{
		printf("EVP_PKEY_set1_RSA err\n");
		RSA_free(rsa);
		EVP_PKEY_free(evpKey);
		return;
	}
	//以下是计算签名代码
	EVP_MD_CTX_init(&mdctx);//初始化摘要上下文
	if(!EVP_SignInit_ex(&mdctx, EVP_md5(), NULL))//签名初始化,设置摘要算法,本例为MD5
	{
		printf("err\n");
		EVP_PKEY_free(evpKey);
		RSA_free(rsa);
		return;
	}
	if(!EVP_SignUpdate(&mdctx, mess1, strlen(mess1)))//计算签名(摘要)Update
	{
		printf("err\n");
		EVP_PKEY_free(evpKey);
		RSA_free(rsa);
		return;
	}
	if(!EVP_SignFinal(&mdctx,sign_value,&sign_len,evpKey))	//签名输出
	{
		printf("err\n");
		EVP_PKEY_free(evpKey);
		RSA_free(rsa);
		return;
	}
	printf("消息\"%s\"的签名值是: \n",mess1);
	for(i = 0; i < sign_len; i++)
	{
		if(i%16==0)
			printf("\n%08xH: ",i);
		printf("%02x ", sign_value[i]);	
	}
	printf("\n");	
	EVP_MD_CTX_cleanup(&mdctx);
	
	printf("\n正在验证签名...\n");
	//以下是验证签名代码
	EVP_MD_CTX_init(&mdctx);//初始化摘要上下文
	if(!EVP_VerifyInit_ex(&mdctx, EVP_md5(), NULL))//验证初始化,设置摘要算法,一定要和签名一致。
	{
		printf("EVP_VerifyInit_ex err\n");
		EVP_PKEY_free(evpKey);
		RSA_free(rsa);
		return;
	}
	if(!EVP_VerifyUpdate(&mdctx, mess1, strlen(mess1)))//验证签名(摘要)Update
	{
		printf("err\n");
		EVP_PKEY_free(evpKey);
		RSA_free(rsa);
		return;
	}	
	if(!EVP_VerifyFinal(&mdctx,sign_value,sign_len,evpKey))//验证签名
	{
		printf("verify err\n");
		EVP_PKEY_free(evpKey);
		RSA_free(rsa);
		return;
	}
	else
	{
		printf("验证签名正确.\n");
	}
	//释放内存
	EVP_PKEY_free(evpKey);
	RSA_free(rsa);
	EVP_MD_CTX_cleanup(&mdctx);
	return;
}
int main()
{ 
	OpenSSL_add_all_algorithms();
	tSign();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值