RSA签名之:RSA加密

RSA加密:

RSA的加密原理我不是很理解。

RSA需要提供一对公钥和私钥。。

发送方利用公钥对原始数据进行加密,接收方利用发送方提供的私钥对密文解密。

C++实现一个RSA加密的demo

老大提供了一个openssl的源码给我。

让我自己先调试成功。。

初次接触RSA加密,我十分迷茫。

大半天的时间才搞定,结果运行时出现了update(******)applink的错误。查了好多资料,最后加上一个applink.c似乎搞定了,但是无法移植。一下子我陷入了僵局,似乎不知道该如何往下面走了。

现在想来,估计是我的key文件没有加载好,导致出现了update的错误。

好不容易调试成功了,

 

接下来又出现问题了。。

提供的公钥居然是证书文件,而我的C++demo似乎只支持key文件。。

PS:其实C++也有函数支持读取证书文件的。只是我当时时间比较紧,没有仔细去钻研了。

 

辛辛苦苦总算将证书转换成key文件了。

 

实现:

读取指定目录/etc/upps/下所有key文件,并将这些key文件加载到内存中,加密时,根据传入的key文件名称选择对应的key加密。

1linux目录下的所有文件:

解决方式:

(1)       手动添加:

这种方式是在代码中手动列出所有的key文件,将key文件依次读入内存中。

#define NUM_KEY 2    //定义key文件数量

const char* rsa_key[NUM_KEY] =  

{

     "/etc/upps/privatekey.key",

     "/etc/upps/mepf_privatekey.key",

//   "/etc/upps/privatekey12.key"

}; for(i=0; i<NUM_KEY; i++)

     {

         RsaKeyFile[i].pKey = load_key(bio_err, rsa_key[i], keyform, 0, passin, 0, "Private Key");   //加载key文件

         strcpy(RsaKeyFile[i].path,rsa_key[i]);

     }

缺点:这种方式调用key需要手动添加key文件,每次增加一个key,需要更新rsa_key 数组和NUM_KEY数量。

(2)       自动读取目录下的所有key

计算目录下的所有key文件数量,并将key 文件名称保存起来。

struct KeyPath   //key的文件名称和RSA指针,EVP_PKEY指针对应起来。

{

         RSA* gRsaKey;

         EVP_PKEY* pKey;

         char path[1024];

}RsaKeyFile[500];

int keyofNum = 0;   //存放key的数量

#ifndef WIN32

//获取key文件数量

int getfilecount(char *path)  

{  

         DIR *dir;  

         int count = 0;

  struct dirent *s_dir;  

  struct  stat file_stat;         

         char currfile[1024]={0};  

         int len = strlen(path);

         if(path[len-1] != '/')

         {

                   path[len] = '/';

                   path[len+1] = 0;

         }

         printf("%s/n",path);

         if( (dir=opendir(path)) == NULL)

         {  

                   printf("opendir(path) error./n");  

                   return -1;  

         }  

   while((s_dir=readdir(dir))!=NULL)  

          {  

        if((strcmp(s_dir->d_name,".")==0)||(strcmp(s_dir->d_name,"..")==0))  

                                     continue;

        sprintf(currfile,"%s%s",path,s_dir->d_name);  

        stat(currfile,&file_stat);  

        if(S_ISDIR(file_stat.st_mode))  ;

 

           if(IsKeyFile(currfile))

           {

              printf("%s/tOK/n",currfile);

                                                  

                                                    printf("数量:%d",count);

                                                    strcpy(RsaKeyFile[count].path,currfile);//保存key的文件名。

                                                    count++;

                   }

    }  

           closedir(dir);  

         return count;  //获取key的数量。

}  

 

//判断文件后缀是否为.key

int IsKeyFile(char *filePath)

{

         char *ptr = NULL;

         //printf("文件路径%s,文件路径长度%d/n",filePath,strlen(filePath));

         ptr = strstr (filePath,".key");

         if(ptr != NULL )

                   return 1;

         else

                   return 0;

}

 

#endif

 

保存key的数量,将key文件名称与RSA EVP_PKEY对应起来。

keyofNum =    getfilecount("/etc/upps/");

for(i=0; i<count; i++)

{

         RsaKeyFile[i].pKey = load_key(bio_err, RsaKeyFile[i].path, keyform, 0, passin, 0, "Private Key");

         //strcpy(RsaKeyFile[i].path,rsa_key[i]);

}

for(i=0;i<count;i++)

{

         RsaKeyFile[i].gRsaKey =  EVP_PKEY_get1_RSA(RsaKeyFile[i].pKey);

         EVP_PKEY_free(RsaKeyFile[i].pKey);

}

 

私钥加密,根据路径选择RSA KEY

__DLL_EXPORT__ int tsRSAPrivateEncrypt(unsigned char *input, unsigned char *output,char* path)

{

 

         keysize = RSA_size(RsaKeyFile[1].gRsaKey);

         rsa_in = OPENSSL_malloc(keysize * 2);

         rsa_out = OPENSSL_malloc(keysize);

……

         for(i=0; i<keyofNum; i++)

         {

                   if(strcmp(path,RsaKeyFile[i].path) == 0)

                   rsa_outlen  = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, RsaKeyFile[i].gRsaKey, RSA_PKCS1_PADDING);

         }

……

}

第二种方式显然比第一种要更好,它能自动读取/etc/upps/目录下所有的文件,并实现自动加载,自动设别key的功能。

 

代码的问题:

tsRSAPrivateEncrypt可能会出现问题,当目录下只有一个key时,RsaKeyFile[1].gRsaKey显然超出了内存范围。

应改为:

__DLL_EXPORT__ int tsRSAPrivateEncrypt(unsigned char *input, unsigned char *output,char* path)

{

……

         for(i=0; i<keyofNum; i++)

         {

                   if(strcmp(path,RsaKeyFile[i].path) == 0)

                   {

                            keysize = RSA_size(RsaKeyFile[i].gRsaKey);

                            rsa_in = OPENSSL_malloc(keysize * 2);

                            rsa_out = OPENSSL_malloc(keysize);

                            rsa_outlen  = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, RsaKeyFile[i].gRsaKey, RSA_PKCS1_PADDING);

         }

……

}

 

由于时间紧迫,暂时无暇改正了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值