您的位置:首页 > 运维架构

vs2012基于openssl实现对文件中数据的签名与验证

2017-04-24 10:01 375 查看
在做这个之前,先要添加openssl的库文件和lib,这个方法参考我的上一篇文章.

3.txt要放到工程目录下

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<windows.h>

#include<openssl/evp.h>

#include<openssl/x509.h>//证书操作函数

void tsign()

{

    FILE *fp;

    unsigned char sign_value[1024];                //保存签名值的数组

    unsigned int sign_len;                         //签名值长度

    EVP_MD_CTX mdctx;                              //摘要算法上下文变量

    char mess[200];

    if((fp=fopen("3.txt","r"))==NULL) exit(0);

    fscanf(fp,"%s",mess);

    fclose(fp);

    printf("\n从文件读取的数据为:%s\n",mess);

    RSA*rsa=NULL;                                  //RSA结构体变量

    EVP_PKEY *evpKey=NULL;                         //EVP KEY结构体变量

    int i;

    printf("正在生成RSA密钥...\n");

    rsa=RSA_generate_key(1024,RSA_F4,NULL,NULL);   //产生一个1024位的RSA密钥

    if(rsa==NULL)

    {

        printf("生成rsa密钥失败\n");

        return;

    }

    printf("生成RSA秘钥成功.\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))     //签名初始化,设置摘要算法,摘要算法引擎

    {                                               //EVP_MD_CTX结构体,MD5摘要算法

        printf("err\n");                            //NULL表示使用默认引擎

        EVP_PKEY_free(evpKey);

        RSA_free(rsa);

        return;

    }

    if(!EVP_SignUpdate(&mdctx,mess,strlen(mess)))        //计算签名(摘要)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",mess);

    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,mess,strlen(mess))) //验证签名摘要值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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: