如何使用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"); } 

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

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

您可以使用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的错误使用 – 您应该只使用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"); } }