openssl rsa 编程问题……很奇怪的加密不同文件时有时候出错有时候不出错

shanshanlong 2010-07-28 10:16:12
如题 有时候出错有时候不出错 完整代码放上



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/rsa.h>
#include <openssl/pem.h>

#include "cc_bel.h"

#define APPLICATION_NAME "cc_RSA"
#define APPLICATION_VERSION "0.99"
#define RSA_PRIVATE_KEY_NAME "rsaprivate.key"
#define RSA_PUBLIC_KEY_NAME "rsapublic.key"


RESULT RSA_Encrypt(char *pszSource_file, char *pszObject_file);
RESULT RSA_Decrypt(char *pszSource_file, char *pszObject_file);
RSA *RSA_read_privatekey(char *pszSource_file);
RSA *RSA_read_publickey(char *pszSource_file);

RESULT main(int argc, char *argv[])
{
printf("Copyright BANKHT %s %s\n\n", APPLICATION_NAME, APPLICATION_VERSION);

char szflag[5];
char szSource_file[32];
char szObject_file[32];

if(argc != 4)
{
printf("\nUsage: makeDES <flag> <Source file> <Object file> <key>\n");
printf("flag -- 标识,为1时进行加密操作,为2时进行解密操作\n");
printf("Source file -- 源文件\n");
printf("Object file -- 目标文件\n");
return FAIL;
}

bel_ClrBuf(szflag);
bel_ClrBuf(szSource_file);
bel_ClrBuf(szObject_file);

strcpy(szflag,argv[1]);
strcpy(szSource_file,argv[2]);
strcpy(szObject_file,argv[3]);

if(strcmp(szflag, "1") == 0)
{
printf("\n您选择的方式是[flag=%s],加密操作\n",szflag);
}
else
{
printf("\n您选择的方式是[flag=%s],解密操作\n",szflag);
}
printf("Source file: %s\n",szSource_file);
printf("Object file: %s\n",szObject_file);

if(strcmp(szflag, "1") == 0)
{
RSA_Encrypt(szSource_file, szObject_file);
}
else
{
RSA_Decrypt(szSource_file, szObject_file);
}

return SUCCESS;
}

RESULT RSA_Encrypt(char *pszSource_file, char *pszObject_file)
{
FILE *pfPlain, *pfCipher;
char *szPlainBlock, *szCipherBlock;
RSA *pRsa;
int iret = -1, flen, icount = -1;

if((pfPlain = fopen(pszSource_file, "rb")) == NULL)
{
printf ("==============\nopen file [ %s ] error!\n==============\n", pszSource_file);
return FAIL;
}
if((pfCipher = fopen(pszObject_file, "wb")) == NULL)
{
printf ("==============\nopen file [ %s ] error!\n==============\n", pszObject_file);
return FAIL;
}
pRsa = RSA_new();
/* 读取密钥 */
pRsa = RSA_read_publickey(RSA_PUBLIC_KEY_NAME);
pRsa = RSA_read_privatekey(RSA_PRIVATE_KEY_NAME);
iret = RSA_check_key(pRsa);
if(iret != 1)
{
printf("key error! \n");
return FAIL;
}

flen = RSA_size(pRsa);
szPlainBlock = (char*)malloc(flen + 1);
szCipherBlock = (char*)malloc(BN_num_bytes(pRsa->n) + 1);

printf("RSA_Encrypt begin ......\n");

while(!feof(pfPlain))
{
/* 每次读8个字节,并返回成功读取的字节数 */
if((icount = fread(szPlainBlock, sizeof(char), flen, pfPlain)) == flen)
{
iret = RSA_public_encrypt(flen, szPlainBlock, szCipherBlock, pRsa, RSA_NO_PADDING);
if (iret < 0)
{
printf("iret = [ %d ]\n", iret);
printf("Encrypt failed! \n");
return FAIL;
}
fwrite(szCipherBlock, sizeof(char), flen, pfCipher);
}
}

if(icount)
{
/* 填充 */
memset(szPlainBlock + icount, '\0', flen - icount);
/* 最后一个字符保存包括最后一个字符在内的所填充的字符数量 */
szPlainBlock[flen - 1] = flen - icount;
iret = RSA_public_encrypt(flen, szPlainBlock, szCipherBlock, pRsa, RSA_NO_PADDING);
if (iret < 0)
{
printf("Encrypt failed! \n");
return FAIL;
}
fwrite(szCipherBlock, sizeof(char), flen, pfCipher);
}

free(szPlainBlock);
free(szCipherBlock);

szPlainBlock=NULL;
szCipherBlock=NULL;

fclose(pfPlain);
fclose(pfCipher);

RSA_free(pRsa);

printf("RSA_Encrypt OK!\n");
return SUCCESS;

}

RESULT RSA_Decrypt(char *pszSource_file, char *pszObject_file)
{
FILE *pfPlain, *pfCipher, *pfkey;
int len, times = 0, flen = 0, icount = -1;
long lFileSize;
char *szPlainBlock, *szCipherBlock;
char *szkey;
RSA *pRsa;

if((pfPlain = fopen(pszObject_file, "wb")) == NULL)
{
printf ("==============\nopen file [ %s ] error!\n==============\n", pszObject_file);
return FAIL;
}
if((pfCipher = fopen(pszSource_file, "rb")) == NULL)
{
printf ("==============\nopen file [ %s ] error!\n==============\n", pszSource_file);
return FAIL;
}

pRsa = RSA_new();
pRsa = RSA_read_privatekey(RSA_PRIVATE_KEY_NAME);

/* 取密文文件长度 */
fseek(pfCipher, 0, SEEK_END); /* 将文件指针置尾 */
lFileSize = ftell(pfCipher); /* 取文件指针当前位置 */
rewind(pfCipher); /* 将文件指针重指向文件头 */

flen = RSA_size(pRsa);

/* 动态分配文件大小的内存给szmol */
szPlainBlock = (char*)malloc(lFileSize);
szCipherBlock = (char*)malloc(lFileSize);


bel_ClrBuf(szCipherBlock);
bel_ClrBuf(szPlainBlock);

while(1)
{
fread(szCipherBlock, sizeof(char), flen, pfCipher);
len = RSA_private_decrypt(flen, szCipherBlock, szPlainBlock, pRsa, RSA_NO_PADDING);

if(len <= 0)
{
printf("RSA_private_decrypt err!\n");
return FAIL;
}
times += flen;
if(times < lFileSize)
{
fwrite(szPlainBlock, sizeof(char), flen, pfPlain);
}
else
{
break;
}
}

/* 判断末尾是否被填充 */
if(szPlainBlock[flen - 1] < flen)
{
for(icount = flen - szPlainBlock[flen - 1]; icount < flen - 1; icount++)
{
if(szPlainBlock[icount] != '\0')
{
break;
}
}
}
if(icount == flen - 1) /* 有填充 */
{
fwrite(szPlainBlock,sizeof(char), flen - szPlainBlock[flen - 1], pfPlain);
}
else /* 无填充 */
{
fwrite(szPlainBlock, sizeof(char), flen, pfPlain);
}

fclose(pfPlain);
fclose(pfCipher);
RSA_free(pRsa);
return SUCCESS;
}

RSA *RSA_read_privatekey(char *pszSource_file)
{
FILE *pfkey;
RSA *pRsa;

if((pfkey = fopen(pszSource_file, "rb")) == NULL)
{
printf ("==============\nopen file [ %s ] error!\n==============\n", pszSource_file);
exit(0);
}

pRsa = RSA_new();
pRsa = PEM_read_RSAPrivateKey(pfkey, NULL, NULL, NULL);

return pRsa;
}

RSA *RSA_read_publickey(char *pszSource_file)
{
FILE *pfkey;
RSA *pRsa;

if((pfkey = fopen(pszSource_file, "rb")) == NULL)
{
printf ("==============\nopen file [ %s ] error!\n==============\n", pszSource_file);
exit(0);
}

pRsa = RSA_new();
pRsa = PEM_read_RSAPublicKey(pfkey, NULL, NULL, NULL);

return pRsa;
}

/*end of this file*/





下面是生成密钥的代码




#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/rsa.h>
#include <openssl/pem.h>

#include "cc_bel.h"

#define APPLICATION_NAME "cc_RSA_makekey"
#define APPLICATION_VERSION "0.99"

#define RSA_PRIVATE_KEY_NAME "rsaprivate.key"
#define RSA_PUBLIC_KEY_NAME "rsapublic.key"

RESULT main()
{
printf("Copyright BANKHT %s %s\n\n", APPLICATION_NAME, APPLICATION_VERSION);

RSA *pRsa;
int bits=1024,iret;
unsigned long e=RSA_3;
BIGNUM *bne;
FILE *pfprivatekey, *pfpublickey;

if((pfpublickey = fopen(RSA_PUBLIC_KEY_NAME, "wb")) == NULL)
{
printf ("==============\nopen file [ %s ] error!\n==============\n", RSA_PUBLIC_KEY_NAME);
exit(0);
}

if((pfprivatekey = fopen(RSA_PRIVATE_KEY_NAME, "wb")) == NULL)
{
printf ("==============\nopen file [ %s ] error!\n==============\n", RSA_PRIVATE_KEY_NAME);
exit(0);
}

pRsa=RSA_generate_key(bits,e,NULL,NULL);
RSA_print_fp(stdout,pRsa,11);

iret = RSA_check_key(pRsa);
if(iret != 1)
{
printf("key error! \n");
return FAIL;
}

/* 写到文件 */
PEM_write_RSAPublicKey(pfpublickey, pRsa);
PEM_write_RSAPrivateKey(pfprivatekey, pRsa, NULL, NULL, bits, NULL, NULL);

RSA_free(pRsa);
fclose(pfpublickey);
fclose(pfprivatekey);

return SUCCESS;
}

...全文
292 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
tangyulong1214 2010-09-01
  • 打赏
  • 举报
回复
搞定了没,我怎么发现你的加密,解密都是用私钥啊。
pRsa = RSA_new();
/* 读取密钥 */
pRsa = RSA_read_publickey(RSA_PUBLIC_KEY_NAME);
pRsa = RSA_read_privatekey(RSA_PRIVATE_KEY_NAME);
iret = RSA_check_key(pRsa);
最后是RSA_read_privatekey。

而在RESULT RSA_Decrypt(char *pszSource_file, char *pszObject_file)函数中:
pRsa = RSA_new();
pRsa = RSA_read_privatekey(RSA_PRIVATE_KEY_NAME);


另外您的程序在多处可能出现内存泄露。
比较肯定的就是RSA_new()这个东西,多处调用肯定有泄露...
rockugrief 2010-08-23
  • 打赏
  • 举报
回复
RSA *RSA_read_publickey(char *pszSource_file)
{
FILE *pfkey;
RSA *pRsa;[code=C/C++]


if((pfkey = fopen(pszSource_file, "rb")) == NULL)
{
printf ("==============\nopen file [ %s ] error!\n==============\n", pszSource_file);
exit(0);
}

pRsa = RSA_new();
pRsa = PEM_read_RSAPublicKey(pfkey, NULL, NULL, NULL);

return pRsa;
}
[/code]
你这个函数返回的是一个局部指针,把它改成static RSA *pRsa,应该就可以了。
wjb_yd 2010-07-29
  • 打赏
  • 举报
回复
加密这方面的东西懂的人比较少...
shanshanlong 2010-07-28
  • 打赏
  • 举报
回复
我晕啊 大大们出现吧
shanshanlong 2010-07-28
  • 打赏
  • 举报
回复
没人理?
shanshanlong 2010-07-28
  • 打赏
  • 举报
回复
没人管没人爱的OPENSSL啊

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧