【问题标题】:How to encrypt large data in C++ using RSA encryption如何使用 RSA 加密在 C++ 中加密大数据
【发布时间】:2014-06-25 07:25:48
【问题描述】:

我使用以下代码在 C++ 中使用 OpenSSL 加密字符串,并且仅当文本达到 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
我应该怎么做才能使它适用于任何大小的字符串?

【问题讨论】:

  • 你可以读取256字节并加密,然后继续
  • 你的意思是我每 256 个字节调用一次这个函数并连接加密内容?
  • 是的,你可以试试。 :-)
  • 建议的链接没有提供解决方案。它建议使用另一个库 Nacl 而不是 OpenSSL。我必须用 OpenSSL 来做。
  • 虽然用 OpenSSL 构建一个安全的加密协议是肯定的可能,但是在没有大量加密背景的情况下构建一个是极不太可能的。 OpenSSL 只是一个糟糕的工具。

标签: encryption openssl rsa


【解决方案1】:

但是如果字符串的大小超过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 结合使用,请在 OpenSSL wiki EVP Authenticated Encryption and Decryption 上查看如何使用它的示例。

有几个密码系统将服务作为一个包提供。见 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

【讨论】:

  • 感谢您提供详细信息。那么,如果我继续使用带有 256 密钥的 OpenSSL 并使用 AES 而不是 RSA,问题会解决吗?
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2010-11-15
    • 2012-01-15
    • 1970-01-01
    • 2013-04-22
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 2019-01-26
    • 2013-03-17
    相关资源
    最近更新 更多