数字签名算法
来源:互联网 发布:中国网络电视直播台 编辑:程序博客网 时间:2024/06/06 00:25
#include<stdio.h>
#include<openssl/evp.h>
#include<string.h>
#include<windows.h>
#include<openssl/x509.h>
void sign_test()
{
unsigned char sign_value[1024]; //保存签名值的数组
int sign_len; //签名的长度
EVP_MD_CTX mdctx; //摘要算法上下文变量
char mess1[]="Text Message"; //签名的信息
RSA *rsa=NULL; //RSA结构体变量
EVP_PKEY *evpKey=NULL; //EVPKEY 结构体变量
int i;
printf("正在产生RSA密钥....");
rsa=RSA_generate_key(1024,RSA_F4,NULL,NULL); //产生一个1024 位的RSA密钥
if (rsa==NULL)
{
printf("gen rsa err\n");
return;
}
printf("成功。\n");
//The EVP_PKEY_new() function allocates an empty EVP_PKEY structure which is used by OpenSSL to store private keys.
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); //初始化摘要上下文
//该函数是一个宏定义函数#define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c)
// int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
//EVP_DigestInit_ex() sets up digest context ctx to use a digest type from ENGINE impl.
//ctx must be initialized before calling this function. type will typically be supplied by a functionsuch as EVP_sha1().
//If impl is NULL then the default implementation of digest type is used.
if (!EVP_SignInit_ex(&mdctx,EVP_md5(),NULL))
{
printf("Init err\n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
//int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
//EVP_DigestUpdate() hashes cnt bytes of data at d into the digest context ctx.
//This function can be called several times on the same ctx to hash additional data.
if (!EVP_SignUpdate(&mdctx,mess1,strlen(mess1))) //计算签名(摘要)Update
{
printf("EVP_SignUpdate err\n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
//int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *sig,unsigned int *s, EVP_PKEY *pkey);
//这是签名系列函数跟信息摘要函数开始不同的地方,其实,该函数是将签名操作的信息摘要结构ctx拷贝一份,
//然后调用EVP_DigestFinal_ex完成信息摘要工作,然后开始对摘要信息用私钥pkey进行签名,并将签名信息保存在参数sig里面。
//如果参数s不为NULL,那么就会将签名信息数据的长度(单位字节)保存在该参数中,通常写入的数据是EVP_PKEY_size(key)。
//因为操作的时候是拷贝了一份ctx,所以,原来的ctx结构还可以继续使用EVP_SignUpdate和EVP_SignFinal函数来完成更多信息的签名工作。
//不过,最后一定要使用EVP_MD_CTX_cleanup函数清除和释放ctx结构,否则就会造成内存泄漏。
if(!EVP_SignFinal(&mdctx,sign_value,(unsigned int *)(&sign_len),evpKey))//签名输出
{
printf("EVP_SignFinal err \n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
printf("消息\"%s\"的签名值是:\n",mess1);
for(i=0;i<sign_len;i++)
{
if (i%6==0)
printf("\n%08xH:",i);
printf("%02x ",sign_value[i]);
}
printf("\n");
EVP_MD_CTX_cleanup(&mdctx);
printf("\n 正在验证签名......\n");
//以下为验证代码
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)))
{
printf ("EVP_VerifyUpdate err \n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
if (!EVP_VerifyFinal(&mdctx,sign_value,sign_len,evpKey))
{
printf("EVP_VerifyFinal 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);
printf ("--------------------------------------\n");
return;
}
#include<openssl/evp.h>
#include<string.h>
#include<windows.h>
#include<openssl/x509.h>
void sign_test()
{
unsigned char sign_value[1024]; //保存签名值的数组
int sign_len; //签名的长度
EVP_MD_CTX mdctx; //摘要算法上下文变量
char mess1[]="Text Message"; //签名的信息
RSA *rsa=NULL; //RSA结构体变量
EVP_PKEY *evpKey=NULL; //EVPKEY 结构体变量
int i;
printf("正在产生RSA密钥....");
rsa=RSA_generate_key(1024,RSA_F4,NULL,NULL); //产生一个1024 位的RSA密钥
if (rsa==NULL)
{
printf("gen rsa err\n");
return;
}
printf("成功。\n");
//The EVP_PKEY_new() function allocates an empty EVP_PKEY structure which is used by OpenSSL to store private keys.
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); //初始化摘要上下文
//该函数是一个宏定义函数#define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c)
// int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
//EVP_DigestInit_ex() sets up digest context ctx to use a digest type from ENGINE impl.
//ctx must be initialized before calling this function. type will typically be supplied by a functionsuch as EVP_sha1().
//If impl is NULL then the default implementation of digest type is used.
if (!EVP_SignInit_ex(&mdctx,EVP_md5(),NULL))
{
printf("Init err\n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
//int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
//EVP_DigestUpdate() hashes cnt bytes of data at d into the digest context ctx.
//This function can be called several times on the same ctx to hash additional data.
if (!EVP_SignUpdate(&mdctx,mess1,strlen(mess1))) //计算签名(摘要)Update
{
printf("EVP_SignUpdate err\n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
//int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *sig,unsigned int *s, EVP_PKEY *pkey);
//这是签名系列函数跟信息摘要函数开始不同的地方,其实,该函数是将签名操作的信息摘要结构ctx拷贝一份,
//然后调用EVP_DigestFinal_ex完成信息摘要工作,然后开始对摘要信息用私钥pkey进行签名,并将签名信息保存在参数sig里面。
//如果参数s不为NULL,那么就会将签名信息数据的长度(单位字节)保存在该参数中,通常写入的数据是EVP_PKEY_size(key)。
//因为操作的时候是拷贝了一份ctx,所以,原来的ctx结构还可以继续使用EVP_SignUpdate和EVP_SignFinal函数来完成更多信息的签名工作。
//不过,最后一定要使用EVP_MD_CTX_cleanup函数清除和释放ctx结构,否则就会造成内存泄漏。
if(!EVP_SignFinal(&mdctx,sign_value,(unsigned int *)(&sign_len),evpKey))//签名输出
{
printf("EVP_SignFinal err \n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
printf("消息\"%s\"的签名值是:\n",mess1);
for(i=0;i<sign_len;i++)
{
if (i%6==0)
printf("\n%08xH:",i);
printf("%02x ",sign_value[i]);
}
printf("\n");
EVP_MD_CTX_cleanup(&mdctx);
printf("\n 正在验证签名......\n");
//以下为验证代码
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)))
{
printf ("EVP_VerifyUpdate err \n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
if (!EVP_VerifyFinal(&mdctx,sign_value,sign_len,evpKey))
{
printf("EVP_VerifyFinal 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);
printf ("--------------------------------------\n");
return;
}
0 0
- 数字签名算法
- 数字签名算法
- 数字签名算法RSA
- 数字签名算法DSA
- 什么是数字签名算法(DSA)
- 数字签名算法概述_JJM
- 数字签名算法RSA_JJM
- 数字签名算法--2.DSA
- 数字签名算法--3.ECDSA
- 数字签名算法-RSA
- RSA数字签名算法
- 数字签名算法DSA
- 数字签名算法为:MD5withRSA
- 国密SM2数字签名算法
- 数字签名算法_RSA
- 数字签名算法_DSA
- 数字签名算法_ECDSA
- 数字签名技术 -- DSA算法
- actioncontext.getcontext()详解
- 需要uac交互的程序如何自启动
- VS调式技巧
- ios应用中添加广告
- Linux下C语言获取某分区剩余空间大小
- 数字签名算法
- 第十一周上机项目六(4)回文素数
- 第11周项目1-2调用函数printchs输出星号图
- String和StringBuffer的区别
- Wikioi P3285 转圈游戏
- 第十一周项目 6 回文,素数(1000以内的素数)
- window下如何使用命令行创建schedule task(计划任务)
- 第十一周项目二:求最大公约数
- 自适应布局