加密API - 块模式加密确定输入字节数

问题描述:

我想加密一些日期使用从CALG_RSA_KEYX键类型所做的交换密钥对派生的公钥。我使用cryptgetkeyparam KP_BLOCKLEN确定块大小为512位。看起来,我可以在53(424位)中提供cryptencrypt的最大字节数,我得到的加密长度为64。我如何确定可以将多少字节送入cryptencrypt?如果我输入超过53个字节,则调用失败。加密API - 块模式加密确定输入字节数

编辑:虽然由OP所接受这种反应被标记,请参阅拉斯穆斯·法伯响应代替,因为这是一个更好的响应。 24小时后发布,Rasmus的回应纠正了事实错误,特别是将OAEP误描述为分组密码; OAEP实际上是一种在PKCS-1的编码原语上用于密钥加密的方案。 OAEP更安全,并且对最大消息长度设置了更大的限制,这个限制也被绑定到散列算法及其密钥长度。

答复如下的另一个缺点是它没有强调CALG_RSA_KEYX应该专门为密钥交换,任何长度的消息的传输后,可发生与任何对称密钥加密算法需要,可使用。 OP意识到了这一点,他只是试图与PK“玩”,尽管在长篇评论中有深度,但我的确涵盖了这么多。

暂时,我在这里留下这个回应,作为记录,还有Mike D可能想提及它,但如果你认为这样做会更好完全删除它;为了清晰起见,我不介意这么做!
      -mjv- 2009年9月29日

原答复:

你检查从GetLastError函数(错误代码),以下cryptencrypt()的虚假申报? 我怀疑它可能是NTE_BAD_LEN,除非有其他问题。

也许你可以发布围绕你的调用criptencryt()的代码。

宾果,看到CryptEncrypt()调用。

由于您没有打开CRYPT_OAEP标志,因此您似乎没有使用RSAES w/OAEP方案。这个OAEP方案是基于RSAES的分组密码。然而,后面的加密算法只能加密比其密钥大小稍小的消息(以字节表示)。这是由于PKCS#1中定义的最小填充大小;这种填充有助于保护算法免受某些关键攻击,我认为基于已知明文的算法)。

因此,你有三种选择:

  • 使用CRYPT_OAEP在标志参数CryptEncrypt()
  • 延长密钥大小说1024(如果你拥有控制权,提防更长的密钥会增加编码/解码的时间...)
  • 限制自己使用短于54字节的明文消息。

为了便于记录,我想记下一些在线资源。

 
- The [RSA Labs][1] web site which is very useful in all things crypto. 
- Wikipedia articles on the subject are also quite informative, easier to read 
    and yet quite factual (I think). 

如果有疑问,但是,千万咨询一个真正加密专家像我:-)

+0

你是对的,错误是NTE_BAD_LEN。 这里的加密电话... \t \t \t如果(!CryptEncrypt(hPublicKey,0,TRUE,0,(无符号字符*)&szMessage,及LL,2048)) 我从调试代码知道,如果DWORD LL包含超过53个,该函数返回一个错误。对于LL = 53,函数成功,LL返回为64,即密钥块大小。 当我读取MSDN时,LL是输入中要加密的字节数,并且改变了对加密文本实际大小的调用。 dwBufLen,第五个参数(2048)可能是可用于加密的缓冲区的实际大小。 – 2009-09-26 13:15:15

+0

我在http://msdn.microsoft.com/en-us/library/ms867086.aspx上发现了更多让我比以往更加困惑的东西。在“加密和解密数据:CryptEncrypt,CryptDecrypt”标题下查看3/4的结尾。 (续)下一条评论 – 2009-09-26 15:21:24

+1

在那里您会找到一个调用cryptencrypt并带有NULL pbData参数的示例,以便查找所需的缓冲区大小。我的困惑出现了,因为1)我们最初拥有DwSize中的数据长度。第一次调用dwSize之后可能会增加,所以第二次调用实际上会加密超过预期的数据。 2)被加密的数据是使用new()获得的缓冲区中剩下的任何垃圾,但也许作者只是选择复制它? – 2009-09-26 15:22:19

RSA使用通常的PKCS#1 v.1.5模式可以加密最多为k-11个字节的消息,其中k是以字节为单位的模数的长度。所以一个512位密钥最多可以加密53个字节,一个1024位密钥最多可以加密117个字节。

使用OAEP的RSA可以对高达k-2 * hLen-2的消息进行加密,其中k是模数字节长度,hLen是基础散列函数输出的长度。因此,使用SHA-1,一个512位密钥可以加密多达22个字节,一个1024位密钥可以加密多达86个字节。

您通常不应该使用RSA密钥直接加密您的消息。相反,您应该生成一个随机对称密钥(f.x. AES密钥),使用对称密钥对您的消息进行加密,使用RSA密钥对密钥进行加密并将两种加密传输给收件人。这通常称为混合加密。

+0

谢谢Rasmus,纠正我的不准确的陈述,并强调RSA = OAEP应专门用作密钥交换协议。尽管我在这一观点中深入阐述了这一点,但重要的是要让这些事情摆在面前,以免未来的读者在我的总体混淆和不准确反应的基础上放松时间并产生有缺陷的实现。我只是在嘲笑OP(我相信他也知道RSA密钥交换的预期用途),试图“玩PK”。我的回应现在“重定向”给你的我的+1,它可能最终浮出水面。 – mjv 2009-09-28 14:56:37

+0

@Rasmus:如果您认为我应该删除我的回复,请告知。 – mjv 2009-09-28 14:57:11

+1

我认为如果你删除它会是一种遗憾。您修复了答案以显示正确答案,评论中的讨论很有意思。 – 2009-09-28 17:35:23