【问题标题】:How to encrypt/decrypt long input messages with RSA? [Openssl, C]如何使用 RSA 加密/解密长输入消息? [Openssl,C]
【发布时间】:2013-10-21 01:37:10
【问题描述】:

我编写了一个简单的测试程序来加密/解密消息。

我有一个keylength

int keylength = 1024; // it can also be 2048, 4096

和最大输入长度:

int maxlen = (keylength/8)-11;

而且我知道我的输入大小应该小于 maxlen,如下所示:

if(insize >= maxlen)
        printf("cannot encrypt/decrypt!\n");

我的问题很简单 - 是否有可能(如果是,我该怎么做)使用 RSA 消息进行加密/解密比 maxlen 更长?

主要代码也很简单,但只有在 insize 时才有效

   if((encBytes=RSA_public_encrypt(strlen(buff1)+1, buff1, buff2, keypair, RSA_PKCS1_PADDING)) == -1)
    {
        printf("error\n");
    }

    if((decBytes=RSA_private_decrypt(encBytes, buff2, buff3, keypair, RSA_PKCS1_PADDING)) == -1)
    {
        printf("error\n");
    }

【问题讨论】:

  • 通常,您使用对称密码(AES 似乎是一种流行的选择)加密您的长消息并使用 RSA 加密 AES 密钥
  • 正如@JoachimIsaksson 指出的那样,您对应用密码学有一个根本的误解。与对称密钥解密相比,RSA 解密为extremely computationally expensive

标签: c encryption cryptography openssl rsa


【解决方案1】:

在这种情况下,您可以使用 RSA 作为分组密码。那就是将消息分成比 maxlen 小的几个块。 否则不可能。

【讨论】:

  • @ivy 使用 RSA 作为分组密码是不切实际的,因为它非常慢。与 AES 相比,一个典型的 CPU 每秒可以 RSA 100 KB 的数据,速度大约快 1,000 到 10,000 倍。
  • @ivy 这只是一个实现错误,与使用 RSA 作为分组密码无关。弗拉德,至少指出了使用混合加密,只是说这是不可能的(尽管严格正确,如果只能使用 RSA)对 Stackoverflow 没有太大帮助。
【解决方案2】:

加密长消息需要组合方案 - RSA 算法加密会话密钥(即 AES 密钥),数据本身使用该密钥加密。 我建议不要发明另一辆自行车并使用完善的方案,即 PKCS#7/CMS 或 OpenPGP,具体取决于您的需要。

【讨论】:

  • “不工作”是什么意思?尽量不要完全填充到模数大小,我猜 RSA_Encrypt 会自行添加填充。
  • “它不起作用”是指它在加密/解密时显示错误 - 不会加密/解密整个消息(即使没有填充)。请查看我的编辑。
【解决方案3】:

您可以使用 RSA 加密长消息,就像使用分组密码一样。即,对块中的消息进行加密,并将块与适当的链接模式绑定。但是,这不是通常的方法,您在使用的库中找不到对它的支持(RSA 链接)。

由于 RSA 非常慢,加密大型消息的常用方法是使用混合加密。在混合加密中,您使用快速对称加密算法(如 AES)使用随机密钥加密数据。然后使用 RSA 对随机密钥进行加密,并与对称密钥加密数据一起发送。

编辑:

在您的实施之前,您有 insize = 1300keylength = 1024,它们给出了 maxlen = 117。要加密完整的消息,您需要 12 次加密,每次产生 128 字节,加密大小为 1536 字节。在您的代码中,您只分配 1416 字节的缓冲区。此外,您似乎不允许输出 128 字节,因为您只增加 117 in:

RSA_public_encrypt(maxlen, buff1+i, buff2+i, keypair, RSA_PKCS1_PADDING)

i += maxlen;

【讨论】:

  • 是的,这些我都知道。关键是,我只想按照您的建议使用 RSA 作为分组密码进行加密/解密。我的主要问题是我在第一篇文章中发布的代码不起作用 - 我总是收到 RSA 加密/解密错误,这就是这个主题的真正问题。你能帮忙吗?
【解决方案4】:

如果您想以“分组密码”类型的模式运行 RSA,则需要循环运行它。

像大多数其他评论者一样,我想指出这是对 RSA 的错误使用 - 您应该只使用 RSA 加密 AES 密钥,然后使用 AES 来处理更长的消息。

但是,我不是那种让实用性妨碍学习的人,所以这就是你的做法。此代码未经测试,因为我不知道您使用的是什么库。为了便于阅读,它也有点过于冗长。

int inLength = strlen(buff1)+1;
int numBlocks = (inLength / maxlen) + 1;

for (int i = 0; i < numBlocks; i++) {
    int bytesDone = i * maxlen;
    int remainingLen = inLength - bytesDone;
    int thisLen; // The length of this block

    if (remainingLen > maxlen) {
       thisLen = maxlen;
    } else {
        thisLen = remainingLen;
    }

    if((encBytes=RSA_public_encrypt(thisLen, buff1 + bytesDone, buff2 + bytesDone, keypair, RSA_PKCS1_PADDING)) == -1)
    {
        printf("error\n");
    }

    // Okay, IDK what the first parameter to this should be. It depends on the library. You can figure it out, hopefully.
    if((decBytes=RSA_private_decrypt(idk, buff2 + bytesDone, buff3 + bytesDone, keypair, RSA_PKCS1_PADDING)) == -1)
    {
        printf("error\n");
    }
}

【讨论】:

    猜你喜欢
    • 2011-02-08
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    • 2018-02-13
    • 2012-04-07
    相关资源
    最近更新 更多