注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

勇敢的劳尤条

 
 
 

日志

 
 

openssl之RSA编程(3)(签名和认证)  

2014-01-13 09:26:19|  分类: 软件安全以及传输 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
继上一篇openssl之RSA加密(2),继续RSA编程,这次主要完成签名和认证。
首先,可以看看签名和认证的接口以及简单说明,链接参看【参考资料】

#include <openssl/rsa.h>
 int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
    unsigned char *sigret, unsigned int *siglen, RSA *rsa);
 int RSA_verify(int type, const unsigned char *m, unsigned int m_len,
    unsigned char *sigbuf, unsigned int siglen, RSA *rsa);

RSA_sign() signs the message digest m of size m_len using the private key rsa as specified in PKCS #1 v2.0. It stores the signature in sigret and the signature size in siglensigret must point to RSA_size(rsa) bytes of memory.

type denotes the message digest algorithm that was used to generate m. It usually is one of NID_sha1NID_ripemd160 and NID_md5; see objects(3) for details. If type is NID_md5_sha1, an SSL signature (MD5 and SHA1 message digests with PKCS #1 padding and no algorithm identifier) is created.

RSA_verify() verifies that the signature sigbuf of size siglen matches a given message digest m of size m_lentype denotes the message digest algorithm that was used to generate the signature. rsa is the signer's public key.


RSA_sign() returns 1 on success, 0 otherwise. RSA_verify() returns 1 on successful verification, 0 otherwise.

RSA_sign,输入m以及m_len,用私钥对其进行签名,并返回签名后的buf:sigret和siglen,并且要求sigret大小至少是RSA_size(rsa) ,这里就是至少128 RSA_verify,所有的参数都是输入,通过返回值为1判断认证成功。输入m以及m_len,sigbuf以及siglen,然后利用公钥rsa进行认证,如果认证成功,返回1。下面是一份代码,用于签名和认证,为简便,生成公钥和私钥的代码去掉了,这部分在以前介绍过了。openssl之RSA加密(2)(产生公钥私钥文件以及加解密)

#include <stdio.h>
#include<string.h>
#include <openssl/bio.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#define MSG_LEN (128+1)

void print_hex(char* buff)
{
for (int i=0;buff[i];i++)
printf("%02x",(unsigned char)buff[i]);
printf("\n");
}
int rsa_verify(char *in, char *key_path, char* in2, int len)
{
RSA *p_rsa;
FILE *file;
if((file=fopen(key_path,"r"))==NULL)
{
perror("open key file error");
return 0;
}
//if((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,&ccbb,NULL))==NULL){
if((p_rsa=PEM_read_RSAPublicKey(file,NULL,NULL,NULL))==NULL)
{
ERR_print_errors_fp(stdout);
return 0;
}
if(!RSA_verify(NID_md5,(unsigned char*)in,strlen(in),(unsigned char*)in2,len,p_rsa))
{
return 0;
}
RSA_free(p_rsa);
fclose(file);
return 1;
}
int rsa_sign(char *in, char *key_path, char* out, int* plen)
{
RSA *p_rsa;
FILE *file;
if((file=fopen(key_path,"r"))==NULL)
{
perror("open key file error");
return 0;
}
if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL)
{
ERR_print_errors_fp(stdout);
return 0;
}
if(!RSA_sign(NID_md5,(unsigned char*)in,strlen(in),(unsigned char*)out,(unsigned int*)plen,p_rsa))
{
return 0;
}
RSA_free(p_rsa);
fclose(file);
return 1;
}
int main(int argc,char**argv)
{
char text[MSG_LEN];
char sign[MSG_LEN];
int len=0;

memset((char*)text, 0 ,MSG_LEN);
memset((char*)sign, 0 ,MSG_LEN);

strcpy((char*)text, "123456789 123456789 123456789 12a");
char pubkey[]="public.rsa";
char prikey[]="private.rsa";
if(!rsa_sign(text,prikey,sign,&len))
{
printf("sign error\n");
return -1;
}
printf("sign %d:",strlen((char*)sign));
print_hex(sign);
if(!rsa_verify(text,pubkey,sign,len))
{
printf("verify error\n");
return -1;
}
printf("verify ok\n");
return 0;
}

至此,签名和认证完成。签名本质上是用私钥进行加密,认证就是用公钥进行解密。因为能用公钥解密,就一定是私钥加密的,所以实现认证。具体看推荐阅读。


  评论这张
 
阅读(4044)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017