[英]How to encrypt/decrypt long input messages with RSA? [Openssl, C]
我写了一个简单的测试程序来加密/解密消息。
我有一个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 = 1300
和keylength = 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");
}
}
maxlen实际上取决于密钥长度和填充模式。 想想更新的填充方案“OAEP”,例如 Java 加密引擎需要额外的 42 个字节而不是 11 个字节。已知的库不是为在块密码模式下使用 RSA 而设计的。
为此,除了上面回答的碎片之外,安全方面还需要进一步修改填充方案,例如https://crypto.stackexchange.com/a/97974/98888
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.