2012-02-14 159 views
0

我使用openssl。首先我创建了私钥/公钥,然后我加密一个字符串并将结果保存在一个文件中。当我尝试解密文件时,我的程序失败了。更重要的是,每次加密的文件都不一样(我使用md5sum选中)。我错过了什么处理?RSA_private_decrypt失败

/* 
    gcc -lssl queation.c -o test_ssl 
    #openssl genrsa -out test_private.key 1024 
    #openssl rsa -in test_private.key -pubout -out test_public.key 

*/ 


#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<openssl/rsa.h> 
#include<openssl/pem.h> 
#include<openssl/err.h> 

#include <errno.h> 
#include <sys/types.h> 
#include <sys/ioctl.h> 
#include <unistd.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <linux/netdevice.h> 
#include <linux/sockios.h> 
#include <linux/if.h> 
#include <asm/types.h> 
#include <linux/netlink.h> 
#include <linux/rtnetlink.h> 
#include <net/if_arp.h> 
#include <netinet/if_ether.h> 
#include <netinet/ether.h> 

#include <fcntl.h> 
#include <sys/socket.h> 

#define OPENSSLKEY "test_private.key" 
#define PUBLICKEY "test_public.key" 
#define BUFFSIZE 1024 
#define SIZE 1024 

#define LIC_FILE "lic.rn" 
#define PRTFL printf("fun = %s, line = %d\n", __FUNCTION__,__LINE__) 

static char *ptr_en; 
static char *p_en; 
static RSA *p_rsa_public; 
static FILE *fp_public; 
static int flen_public, rsa_public_len; 


static char *ptr_de; 
static char *p_de; 
static RSA *p_rsa_private; 
static FILE *fp_private; 
static int flen_private, rsa_private_len; 

void usage(unsigned char * prog_name) 
{ 
    printf("usage: %s\n", 
     prog_name); 
    exit(1); 
} 

int main(int argc , char ** argv) 
{ 
    int i, ret , len; 
    unsigned char buf_plain[32]; 
    unsigned char *buf_en; 
    unsigned char *raw_buffer; 

    FILE * pf_tmp; 

    if(argc != 1) 
     { 
     usage(argv[0]); 
     } 

    snprintf(buf_plain,sizeof(buf_plain),"this is a test line.\n"); 

    if((fp_public=fopen(PUBLICKEY,"r"))==NULL) 
     { 
     perror("open public key file error"); 
     ret = -1; 
     goto error; 
     } 

    if((p_rsa_public = PEM_read_RSA_PUBKEY(fp_public,NULL,NULL,NULL))==NULL) 
     { 
     ERR_print_errors_fp(stdout); 
     ret = -1; 
     goto error; 
     } 

    rsa_public_len=RSA_size(p_rsa_public); 
    p_en=(unsigned char *)malloc(rsa_public_len+1); 
    memset(p_en,0,rsa_public_len+1); 
    //printf("%s(%d)p_en = %p,rsa_public_len = %d\n", __FUNCTION__,__LINE__,p_en,rsa_public_len); 

    len = RSA_public_encrypt(rsa_public_len,buf_plain,p_en,p_rsa_public,RSA_NO_PADDING); 
    if (len !=rsa_public_len) 
     { 
     fprintf(stderr,"Error: len =%d, rsa_public_len = %d,ciphertext should match length of key\n", len,rsa_public_len); 
     ret = -1; 
     goto error; 
     } 


    pf_tmp = fopen(LIC_FILE,"w"); 
    if(NULL == pf_tmp) 
     { 
     printf("open %s failed\n",LIC_FILE); 
     ret = -1; 
     goto error; 
     } 

    fwrite(p_en,1,128,pf_tmp); 
    fclose(pf_tmp); 

    if((fp_private=fopen(OPENSSLKEY,"r"))==NULL) 
     { 
     perror("open private key file error"); 
     ret = -1; 
     goto error; 
     } 

    if((p_rsa_private=PEM_read_RSAPrivateKey(fp_private,NULL,NULL,NULL))==NULL) 
     { 
     ERR_print_errors_fp(stdout); 
     ret = -1; 
     goto error; 
     } 

    rsa_private_len = RSA_size(p_rsa_private); 

    pf_tmp = fopen(LIC_FILE,"r"); 
    if(NULL == pf_tmp) 
     { 
     printf("open %s failed\n",LIC_FILE); 
     ret = -1; 
     goto error2; 
     } 

    raw_buffer = calloc(rsa_private_len,sizeof(char)); 
    if(NULL == raw_buffer) 
     { 
     ret = -1; 
     goto error; 
     } 

    len = fread(raw_buffer, sizeof(char),sizeof(raw_buffer), pf_tmp); 
    if(len <=0) 
     { 
     ret = -1; 
     goto error; 
     } 

    p_de=(unsigned char *)malloc(rsa_private_len+1); 
    memset(p_de,0,rsa_private_len+1); 

    //printf("%s(%d)p_en = %p,rsa_public_len = %d\n", __FUNCTION__,__LINE__,p_en,rsa_public_len); 
    len =RSA_private_decrypt (rsa_private_len,raw_buffer,p_de,p_rsa_private,RSA_NO_PADDING); 
    printf("%s(%d) p_de = %s\n",__FUNCTION__,__LINE__,p_de); 
    if (len != rsa_private_len) 
     { 
     fprintf(stderr,"Error: ciphertext should match length of key\n"); 
     exit(1); 
     } 

error2: 
    fclose(pf_tmp); 

error: 
    free(ptr_en); 
    free(ptr_de); 
    fclose(fp_public); 
    fclose(fp_private); 
    RSA_free(p_rsa_public); 
    RSA_free(p_rsa_private); 

    return ret; 
} 
+0

由于随机填充,预计正确操作的RSA加密每次都会产生不同的结果。 – caf 2012-02-15 04:13:46

+0

非常感谢。 – mrliusz 2012-02-15 05:03:35

回答

2

看起来你是不读的整个文件:

len = fread(raw_buffer, sizeof(char),sizeof(raw_buffer), pf_tmp); 

注意sizeof(raw_buffer)是一个指针的大小,但你写128个字节到文件(1024位)。所以你只能读回4或8个字节并试图解密。

尝试读128个字节回来。

+0

谢谢Omri Barel,它现在可以工作。另一个问题是为什么每个加密字符串/文件是不同的?我感到很困惑。 – mrliusz 2012-02-15 04:55:22

+0

@mrliusz - 每个加密都是随机的。对于算法的每次运行它都会产生不同的结果。 – jww 2014-08-09 23:48:23