如何使用RSA加密在C ++中加密大数据

时间:2014-06-25 07:25:49

标签: encryption openssl rsa

我使用以下代码用OpenSSL加密C ++中的字符串,并且只有当文本达到256字节时它才能正常工作,它不适用于更大的尺寸:

void encrypt(char* message, int sourceSzie, char* encryptedMessage, int &destSize)
{
    char err[130];
    RSA *rsa_pubkey = NULL;
    FILE *rsa_pub_file = fopen("pubkey_file.bin", "rb");

    if(PEM_read_RSAPublicKey(rsa_pub_file, &rsa_pubkey, NULL, NULL) == NULL)
    {
        printf("Error reading public key \n");
    }

    if((destSize = RSA_public_encrypt(sourceSzie, (unsigned char*)message,  (unsigned char*)encryptedMessage, rsa_pubkey,     RSA_PKCS1_OAEP_PADDING)) == -1)
    {
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
    }
    fclose(rsa_pub_file);
}

char msg[1024];
stcpy(msg, "A test message");
int size;
char encrypted[1024];
encrypt(msg, strlen(msg), encrypted, size);

但是如果字符串的大小超过256,则它不起作用并生成Data too large error 我该怎么做才能使它适用于任何大小的字符串?

2 个答案:

答案 0 :(得分:2)

  

但是如果字符串的大小超过256,则它不起作用并生成数据太大的错误。

正确。 RSA加密定义为c = m ^ e mod n。消息不能大于模数大小n。您可以使用RSA_size()获得模数大小。

更准确地说,限制为modulus size - padding size,因为邮件是填充的。 OAEP填充大小约为41个字节,因此限制大约为RSA_size(rsa) - 41

我省略了PKCS填充,因为它不安全。在来源中,它是#define RSA_PKCS1_PADDING_SIZE 11。有关平易近人的讨论,请参阅A bad couple of years for the cryptographic token industry

  

如何使其适用于任何大小的字符串?

您需要一个任意大的密钥;)但OpenSSL将密钥大小限制为16K位。所以你不能把钥匙任意大。

另外,很难生成那些大键。生成时间随密钥大小而增长,您可能需要花费几天时间生成大密钥。

在您的特定情况下:

char msg[1024];
...
encrypt(rsa, msg, sizeof(msg), ...);

尝试生成一个(1024 + 64)* 8或8704位的密钥。那应该用填充来处理1024字节的缓冲区。


要在这种情况下使用公钥加密,您应该使用AES等对称密码加密字符串。然后,使用公共RSA密钥加密AES密钥。这基本上就是SSL / TLS和其他人的运作方式。

如果您使用混合加密,则应选择EAXGCM等模式;和 CBC模式。 EAXGCM是经过身份验证的加密模式,它们提供机密性和真实性。通过经过身份验证的加密,您将提供隐私能够检测到篡改。

如果您选择将OpenSSL与AES / GCM一起使用,请参阅EVP Authenticated Encryption and Decryption上OpenSSL wiki上如何使用它的示例。

有一些密码系统将服务作为一个包提供。见Shoupe的Elliptic Curve Integrated Encryption Scheme(ECIES);或Abdalla,Bellare和Rogaway的Diffie-Hellman Authenticates Encryption Schemes(DHAES)。不幸的是,OpenSSL也没有提供。

但如果您对ECIES或DHAES感兴趣,请查看Crpyto++。图书馆提供了这两个。有关在Crypto ++中使用它的示例,请参阅Elliptic Curve Integrated Encryption Scheme

答案 1 :(得分:2)

我在链接https://shanetully.com/2012/06/openssl-rsa-aes-and-c/找到了解决方案。

函数Crypto::aesEncrypt()Crypto::aesDecrypt()能够加密/解密任意大小的字符串。