精通pki网络安全认证技术与编程实现(读书笔记5)

第五章 OpenSSL签名和验证

数据签名其实就是对数据的摘要进行私钥加密。验证签名就是解密签名数据,和原始的摘要是否一样。OpenSSL中签名,是先对原始数据计算摘要,再对摘要进行私钥加密。验证的过程是对原始消息计算摘要,解密签名值,和摘要对比是否一致。如果一致,说明签名有效;否则,则认为原名 或签名值被篡改。数字签名结合数字证书可以实现身份认证、防篡改、防抵赖的功能。签名的数据格式为PKCS#1。

#include 
  
  
   
   
#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     


      
      void tSign()
{
	
      
      unsigned 
      
      char sign_value[1024];					
      
      //保存签名值的数组
	
      
      int sign_len;									
      
      //签名值长度
	EVP_MD_CTX mdctx;								
      
      //摘要算法上下文变量
	
      
      char mess1[] = "
      
      Test Message";					
      
      //待签名的消息
	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密钥
	
      
      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;
}
     
     
    
    
   
   
  
  
gcc main.c -lssl
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值