2016-11-21 846 views
0

在代码中,我有一个文件,它被分成256个字节块以便用填充进行加密,但是当我打电话给RSA_public_encrypt时,它返回-1,无法理解我做了什么错误。任何人都可以引导我到底哪里出错?RSA_public_encrypt返回-1且无法解密,RSA 2048位填充用于加密和解密文件

#include <openssl/pem.h> 
#include <openssl/ssl.h> 
#include <openssl/rsa.h> 
#include <openssl/evp.h> 
#include <openssl/bio.h> 
#include <openssl/err.h> 
#include <stdio.h> 

int padding = RSA_PKCS1_PADDING; 


RSA * createRSAWithFilename(char * filename,int public) 
{ 
    RSA *rsa= NULL; 
    FILE * fp = fopen(filename,"rb"); 

    if(fp == NULL) { 
     printf("Unable to open file %s \n",filename); 
     return NULL; 
    } 
    if(public) { 
     rsa =PEM_read_RSA_PUBKEY(fp, &rsa,NULL, NULL); 
    } 
    else { 
     rsa = PEM_read_RSAPrivateKey(fp, &rsa,NULL, NULL); 
    } 
    if(rsa == NULL) { 
     printf("Failed to create RSA"); 
    } 

    return rsa; 
} 


int main() { 
    FILE * fp = fopen("hello.c", "rb"); 
    fseek(fp, 0, SEEK_END); 
    int file_size = ftell(fp); 
    fseek(fp, 0, SEEK_SET); 

    char msg_blocks[2048/8]; 
    unsigned char file_encrypt_buf[4098]= {}; 
    size_t bytesRead; 
    int encrypted_length=0; 
    int encrypt_size; 
    FILE *append = fopen("out.bin", "a+"); 
    RSA * rsa1= createRSAWithFilename("public.pem",1); 
    if (fp != NULL) 
    { 
     while ((bytesRead = fread(msg_blocks, sizeof(unsigned char),sizeof(msg_blocks), fp)) > 0) 
     { 
      printf("bytesread %d\n",bytesRead); 
      printf("%d\n",strlen(msg_blocks)); 
      encrypted_length= RSA_public_encrypt(strlen(msg_blocks),(unsigned char*)msg_blocks,(unsigned char*)file_encrypt_buf,rsa1,padding); 
      fwrite(file_encrypt_buf,sizeof(unsigned char),sizeof(file_encrypt_buf),append); 
      printf("encrypted length: %d\n",encrypted_length); 
     } 
     fclose(append); 
     fclose(fp); 
    } 
    printf("Encrypted message written to file.\n"); 

    //decryption 
    append = fopen("out.bin", "r"); 
    fseek(append, 0, SEEK_END); 
    encrypt_size = ftell(append); 
    fseek(append, 0, SEEK_SET); 
    char decrypt_msg_blocks[2048/8]; 
    size_t decryptbytesRead; 
    int decrypted_length=0; 
    unsigned char file_decrypt_buf[4098]={}; 
    FILE * fp1 = fopen("hellodec.c", "a+"); 
    RSA * rsa2= createRSAWithFilename("private.pem",0); 
    if(append!=NULL) { 
     while ((decryptbytesRead = fread(decrypt_msg_blocks, sizeof(unsigned char),sizeof(decrypt_msg_blocks), append)) > 0) { 
      decrypted_length=RSA_private_decrypt(strlen(decrypt_msg_blocks),(unsigned char*)decrypt_msg_blocks, (unsigned char*)file_decrypt_buf, rsa2,padding); 
      fwrite(file_decrypt_buf,,sizeof(unsigned char), sizeof(file_decrypt_buf), fp1); 
     } 
     fclose(fp1); 
     fclose(append); 
    } 
    printf("Decrypted message written to file.\n"); 
    return 0; 
} 

获得以下错误:

bytesread 256 
256 
encrypted length: -1 
bytesread 256 
256 
encrypted length: -1 
bytesread 202 
256 
encrypted length: -1 
encrypted length: -1 
Encrypted message written to file. 
+1

即使您发现错误,它仍然不起作用:256字节太多无法用2048位RSA密钥加密。 –

回答

1

为填充使用了一些空间,不能加密与2048位密钥的完整的256字节的块。 A PKCS1填充使用大约11个字节。实际上这意味着你加密的数据将会越来越大。

一般RSA不适合批量加密,因为它非常慢(与AES相比超过1000倍)。如果可以,请使用对称加密算法,如AES。如果您确实需要RSA的两个密钥,请使用Hybrid方法,即使用随机对称密钥对数据进行加密,然后使用RSA密钥加密该密钥。

对称加密的另一个好处是,库自动支持批量加密,在加密之前,您不需要处理将数据分成小块。

+0

@ Ebbe M. Pedersen,这是有道理的。所以如果我想采用混合方法来加密/解密大文件,我可以使用AES 256 cbc然后使用RSA 2048位密钥,还是应该使用AES 128 cbc? – pavikirthi

+0

[这篇文章](http://crypto.stackexchange.com/questions/8687/security-strength-of-rsa-in-relation-with-the-modulus-size)表明,如果RSA的AES-128可能就足够了-2048就足够了。 –