RSA_public_encrypt返回-1并且无法解密,带填充的RSA 2048位用于加密和解密文件

时间:2016-11-21 00:09:52

标签: c encryption rsa

在代码中,我有一个文件,分为256个字节块以便用填充加密,但是当我调用RSA_public_encrypt时,它返回-1,无法理解我做了什么错。可以任何人指导我到底哪里出错?

#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 个答案:

答案 0 :(得分:1)

您无法使用2048位密钥加密完整的256字节块,因为填充使用了一些空间。 PKCS1 填充使用大约11个字节。实际上,这意味着加密数据的大小将会不断增长。

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

对称加密的另一个好处是,库自动支持批量加密,您无需在加密前将数据切换成小块。