如何使用RSA加密/解密长输入消息? [Openssl,C]

时间:2013-10-13 10:25:53

标签: c encryption cryptography openssl rsa

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

我有keylength

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

和最大输入长度:

int maxlen = (keylength/8)-11;

我知道我的输入大小应该是<比maxlen,像这样:

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

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

主要代码也非常简单,但只有在insize<的maxlen:

   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");
    }

4 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:2)

在这种情况下,您可以使用RSA作为分组密码。这就是把信息打破到比maxlen小的几个街区。 否则不可能。

答案 2 :(得分:2)

您可以使用 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;

答案 3 :(得分:1)

如果要以“分组密码”模式运行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");
    }
}