直接签名
#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;
}