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

openssl RSA 非对称加解密

2015-02-12 11:31 351 查看
一直在研究数据加密与解密,一直都没有好好的整理过这些知识,趁现在有时间,稍加整理,以便更多的人知道如何去加解密数据,少走弯路。相关的整理文档可能后续会以电子版pdf的形式发出来。

非对称加密算法安全性确实相对更高,但同样效率/速度也更低一些,毕竟非对称加密的计算量更大。

RSA是目前使用最广的一种非对称加密算法,既可以对数据进行加密解密,也可以对数据进行签名验证。

使用C/C++ 调用openssl/crypt库写了一个简单的代码,同时实现对数据的非对称加密及对数据的签名验证。

<pre name="code" class="cpp">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rsa.h"
#include "err.h"
#include "bn.h"
#include "objects.h" // for RSA_sign() type -- type is defined in this header file

#define RET_IF_EQ(ret,val,r,msg){\
if(ret == val){\
fprintf(stderr,"%s failed \n",msg);\
return r;\
}else{\
fprintf(stderr,"%s success\n",msg);\
}\
}

int RSA_INFO(RSA *rsa,char *msg){
fprintf(stderr,"-----------%s----------\n",msg);
fprintf(stderr,"n:[%s]\n",BN_bn2hex(rsa->n));
fprintf(stderr,"e:[%s]\n",BN_bn2hex(rsa->e));
fprintf(stderr,"d:[%s]\n",BN_bn2hex(rsa->d));
fprintf(stderr,"p:[%s]\n",BN_bn2hex(rsa->p));
fprintf(stderr,"q:[%s]\n",BN_bn2hex(rsa->q));
fprintf(stderr,"dmp1:[%s]\n",BN_bn2hex(rsa->dmp1));
fprintf(stderr,"dmq1:[%s]\n",BN_bn2hex(rsa->dmq1));
fprintf(stderr,"iqmp:[%s]\n",BN_bn2hex(rsa->iqmp));
return 0;
}

int init_rsa_key(RSA **rsa,RSA **rsa_pub,RSA **rsa_pri){
int ret = 0;

BIGNUM *ex = BN_new();
BN_hex2bn(&ex,"03");
*rsa = RSA_new();
RET_IF_EQ(*rsa,NULL,-1,"RSA_new() rsa");
ret = RSA_generate_key_ex(*rsa,1024,ex,NULL);
RET_IF_EQ(*rsa,NULL,-1,"rsa_generate_key_ex()");
ret = RSA_check_key(*rsa);
fprintf(stderr,"check_key() ret[%d]\n",ret);
RSA_INFO(*rsa,"rsa");
*rsa_pub = RSA_new();
RET_IF_EQ(*rsa_pub,NULL,-1,"RSA_new() rsa_pub");
*rsa_pri = RSA_new();
RET_IF_EQ(*rsa_pri,NULL,-1,"RSA_new() rsa_pri");

// rsa_pub
(*rsa_pub)->n = BN_dup((*rsa)->n);
(*rsa_pub)->e = BN_dup((*rsa)->e);

/*
(*rsa_pub)->d = BN_dup((*rsa)->d);
(*rsa_pub)->p = BN_dup((*rsa)->p);
(*rsa_pub)->q = BN_dup((*rsa)->q);
(*rsa_pub)->dmp1 = BN_dup((*rsa)->dmp1);
(*rsa_pub)->dmq1 = BN_dup((*rsa)->dmq1);
(*rsa_pub)->iqmp = BN_dup((*rsa)->iqmp);
*/

// rsa_pri
(*rsa_pri)->n = BN_dup((*rsa)->n);
(*rsa_pri)->e = BN_dup((*rsa)->e);
(*rsa_pri)->d = BN_dup((*rsa)->d);

/*
(*rsa_pri)->p = BN_dup((*rsa)->p);
(*rsa_pri)->q = BN_dup((*rsa)->q);
(*rsa_pri)->dmp1 = BN_dup((*rsa)->dmp1);
(*rsa_pri)->dmq1 = BN_dup((*rsa)->dmq1);
(*rsa_pri)->iqmp = BN_dup((*rsa)->iqmp);
*/

return 0;
}

int init_default_key(RSA **rsa,RSA **rsa_pub,RSA **rsa_pri){

*rsa_pub = RSA_new();
*rsa_pri = RSA_new();

static unsigned char n[] =
"ED636F2A9C9EB0660120049548C384630F7775447EA765E3D8DF5EBEBC0A0F1839DC82C45FB82C2F9A1CE9CD16491B88C5375F2DDDE1ACDDDAD7BBAAEC9FD447B1142488F73ED2B364669D8295089350910FF912F070C3C448014B9C44D32A1321E2B36A26FADCEDA071E532C8796B79FECE25BF971BA520AA4810ACA9E491E9";

static unsigned char e[] =
"03";

static unsigned char d[] =
"9E424A1C6869CAEEAB6AADB8DB2D02ECB4FA4E2DA9C4EE97E5EA3F29D2B15F657BE8572D952572CA66BDF1336430BD05D8CF94C93E96733E91E527C7486A8D83D8069A34467D90F3A37133F3206EF894776C54BAF6294582FC4709CEFB0D0C4250CCC0CDA6CD5938657CA5D6E466DD8483A7BB429A9737D4660DDE4783C2A8E3";

static unsigned char p[] =
"F757805743B0FAE28A370603562FBB9B107B3B558B438E75CA523A364A185F2601FCDF77EBE29129C7070604C97CD59D99F68859F9B6EB103AD6B5B4E9F4EE47";

static unsigned char q[] =
"F5B2BCE349D17E636505C9928E3262D6CD723EA4F3EF4D0A034482AF82273889A6B2B2BDC0E445EF412FE66BA86249959F5C0481B581E651D65C8D8C7A4BA64F";

static unsigned char dmp1[] =
"A4E5003A2D20A741B17A0402397527BCB5A77CE3B22D09A3DC36D17986BAEA1956A894FA9D41B61BDA04AEADDBA88E69114F059151249CB57C8F23CDF14DF42F";

static unsigned char dmq1[] =
"A3CC7DECDBE0FEECEE03DBB70976EC8F33A17F18A29F88B1578301CA56C4D05BC47721D3D5ED83F4D61FEEF270418663BF92ADABCE56998BE43DB3B2FC326EDF";

static unsigned char iqmp[] =
"AA8591E0EF194760D32CE1397488875FB58A2E7287C7FE8CA4C76F25EA3305F3DD0BFA9FF9D42779D04F6FA2F9F999CFCC174D78920CE7BF4E97E7F750C69FE6";

(*rsa_pub)->n = BN_new();BN_hex2bn(&((*rsa_pub)->n),n);
(*rsa_pub)->e = BN_new();BN_hex2bn(&((*rsa_pub)->e),e);

/*
(*rsa_pri)->d = BN_new();BN_hex2bn(&((*rsa_pri)->d),d);
(*rsa_pri)->p = BN_new();BN_hex2bn(p,sizeof(p)-1,(*rsa_pri)->p);
(*rsa_pri)->q = BN_new();BN_hex2bn(q,sizeof(q)-1,(*rsa_pri)->q);
(*rsa_pri)->dmp1 = BN_new();BN_hex2bn(&((*rsa_pri)->dmp1),dmp1);
(*rsa_pri)->dmq1 = BN_new();BN_hex2bn(&((*rsa_pri)->dmq1),dmq1);
(*rsa_pri)->iqmp = BN_new();BN_hex2bn(&((*rsa_pri)->iqmp),iqmp);
*/

(*rsa_pri)->n = BN_new();BN_hex2bn(&((*rsa_pri)->n),n);
(*rsa_pri)->d = BN_new();BN_hex2bn(&((*rsa_pri)->d),d);
(*rsa_pri)->e = BN_new();BN_hex2bn(&((*rsa_pri)->e),e);
/*
(*rsa_pri)->p = BN_new();BN_hex2bn(p,sizeof(p)-1,(*rsa_pri)->p);
(*rsa_pri)->q = BN_new();BN_hex2bn(q,sizeof(q)-1,(*rsa_pri)->q);
(*rsa_pri)->dmp1 = BN_new();BN_hex2bn(&((*rsa_pri)->dmp1),dmp1);
(*rsa_pri)->dmq1 = BN_new();BN_hex2bn(&((*rsa_pri)->dmq1),dmq1);
(*rsa_pri)->iqmp = BN_new();BN_hex2bn(&((*rsa_pri)->iqmp),iqmp);
*/

return 0;
}
int ras_test(char *buf1,int len1,RSA *rsa_pub,RSA *rsa_pri){
int ret = 0;
int len2,len3;
int rsa_len = RSA_size(rsa_pub);
fprintf(stderr,"RSA_size:[%d]\n",rsa_len);
len2 = len3 = rsa_len;
char *buf2 = (char *)malloc(rsa_len);
char *buf3 = (char *)malloc(rsa_len);

len2 = RSA_public_encrypt(len1,buf1,buf2,rsa_pub,RSA_PKCS1_PADDING);
fprintf(stderr,"encrypt ret[%d] len1:[%d] len2:[%d]\n",ret,len1,len2);
len3 = RSA_private_decrypt(len2,buf2,buf3,rsa_pri,RSA_PKCS1_PADDING);
fprintf(stderr,"decrypt ret[%d] len2:[%d] len3:[%d]\n",ret,len2,len3);

if(len1 == len3 && memcmp(buf1,buf3,len1)==0){
fprintf(stderr,"rsa test(public-private) success.\n");
}else{
fprintf(stderr,"rsa test(public-private) failed.\n");
}

memset(buf2,0,rsa_len);
memset(buf3,0,rsa_len);

len2 = RSA_private_encrypt(len1,buf1,buf2,rsa_pri,RSA_PKCS1_PADDING);
fprintf(stderr,"private encrypt ret[%d] len1:[%d] len2:[%d]\n",ret,len1,len2);
len3 = RSA_public_decrypt(len2,buf2,buf3,rsa_pub,RSA_PKCS1_PADDING);
fprintf(stderr,"public decrypt ret[%d] len2:[%d] len3:[%d]\n",ret,len2,len3);

if(len1 == len3 && memcmp(buf1,buf3,len1)==0){
fprintf(stderr,"rsa test(private-public) success.\n");
}else{
fprintf(stderr,"rsa test(private-public) failed.\n");
}
// verify
ret = RSA_sign(NID_sha1,buf1,len1,buf2,&len2,rsa_pri);
fprintf(stderr,"RSA_sign() ret:[%d] [1:success,0:failed] len2:[%d]\n",ret,len2);
long err = ERR_get_error();
ERR_error_string(err,buf3);
fprintf(stderr,"err:[%d] msg:[%s]\n",err,buf3);

ret = RSA_verify(NID_sha1,buf1,len1,buf2,len2,rsa_pub);
fprintf(stderr,"RSA_verify() ret:[%d] [1:success,0:failed]\n",ret);
err = ERR_get_error();
ERR_error_string(err,buf3);
fprintf(stderr,"err:[%d] msg:[%s]\n",err,buf3);

// error_verify
ret = RSA_verify(NID_sha1,buf1,len1,buf3,len2,rsa_pub);
fprintf(stderr,"RSA_verify() ret:[%d] [1:success,0:failed]\n",ret);
err = ERR_get_error();
ERR_error_string(err,buf3);
fprintf(stderr,"err:[%d] msg:[%s]\n",err,buf3);

free(buf2);
free(buf3);

return ret;
}

#define BUF_SIZE 50
int main(int argc, char ** args){

RSA *rsa = NULL;
RSA *rsa_pub = NULL;
RSA *rsa_pri = NULL;
int ret = init_rsa_key(&rsa,&rsa_pub,&rsa_pri);
//int ret = init_default_key(&rsa,&rsa_pub,&rsa_pri);

char *buf1 = (char *)malloc(BUF_SIZE + 128);

int i,len1;
len1 = BUF_SIZE;
for(i=0;i<BUF_SIZE;i++){
buf1[i] = i%256;
}

ras_test(buf1,len1,rsa_pub,rsa_pri);

RSA_free(rsa);
RSA_free(rsa_pub);
RSA_free(rsa_pri);

return 0;
}
//
// RSA 非对称加密解密,数字签名及验证
//



本代码在 openssl-1.0.1k版本下验证通过,之前的一个openssl版本程序一直出不了结果,不确定是否由于测试机器有多个openssl版本,导致此类异常。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息