使用AES解密少量字节

时间:2012-02-08 22:26:26

标签: c# .net aes

我正在尝试解密我通过TCP套接字接收的一些数据。这是在CFB模式下使用RijndaelManaged类完成的。我的问题是,我不确定我应该如何解密数据,因为我只处理几个字节(8到20取决于消息)。当我用10字节TransformFinalBlock调用byte[]时,我收到一条异常消息:“要解密的数据长度无效。”如果我用这10个字节调用TransformBlock,我得到:“值无效。”所以这是我的问题:

  1. 我收到的消息在前4个字节中具有剩余消息的长度。我怎样才能解密那些字节以确定继续阅读的长度?
  2. 即使我暂时将要读取的字节数硬编码为10(对于此特定消息)并从网络中读取这些字节,我该如何解密这10个字节?
  3. 我还尝试使用CryptoStream直接从我的NetworkStream读取。但是,对它的任何读取调用似乎无限期地阻塞。我有一种感觉,它期待发送更多数据(可能是一个完整的块大小的字节)。

    我无法访问在网络上发送此数据的其他节点,因此我无法更改协议以在开头包含指示长度或任何内容的未加密字节。此外,据说还有其他人成功地与之沟通,所以一定有可能。

3 个答案:

答案 0 :(得分:1)

当使用特定块大小为N的密码系统时,输出中的每个位都取决于输入中至少N位的状态。在许多现代系统如AES的情况下,块大小将是128或256位(即16或32字节)。尽管存在加密文件的方案,其长度不是块大小的倍数而不需要填充(例如,如果文件是256位的某个倍数,加上额外的32位,通常的方案是通过加密a来结束加密。由最后224个加密位和剩余的32个未加密位组成的块)通常不可能加密小于块的任何东西。

您必须加密文件的前16/32字节,使用长度,然后将您读取的“额外”12或28字节视为第一个数据项的一部分,否则需要该数据项最小长度为16或32字节,并分别加密,保留未加密的长度。

答案 1 :(得分:1)

我能够通过使用BouncyCastle库而不是内置的.NET AES类来部分解决这个问题(我的#2问题)。

我首先尝试使用PKCS7手动填充加密数据(我相信这是AES支持的唯一填充方案)。在此手动填充数据上使用RijndaelManaged类导致“填充无效且无法删除”异常。所以我接着尝试使用BouncyCastle库:

CfbBLockCipher cipher = new CfbBlockCipher(new AesEngine(), 128);
cipher.Init(false, new ParametersWithIV(new KeyParameters(key), iv));
cipher.DecryptBlock(encrypted, 0, decrypted, 0);

它完美无缺。我不知道这是否是.NET中的一个错误或什么,但希望这将有助于其他任何人遇到这个。

现在,如果我能弄清楚如何解密前四个字节,那么我知道消息将持续多长时间......(我的第一个问题)

编辑: 如果我使用BouncyCastle的PaddedBufferBlockCipher我在解密时遇到“pad block corrupted”错误。这些数据有些奇怪,我只能在一个块中手动解密,只能使用BouncyCastle(.NET的TransformBlock只给出零字节的解密值。)

答案 2 :(得分:0)

当您处理TCP流时,如果使用长度前缀,通常必须以某种形式缓冲数据,当读取时,您有一个“读取长度”阶段,当该长度时切换到“读取数据”如果满足,则传出已读取的字节并切换回“读取长度”......

记住,您可能无法在一次阅读中收到您发送的所有内容,或者您​​可能会在一次阅读中收到多封发送。

长度是否也加密了?可能是长度以未加密的方式进行,然后有效载荷被加密了吗? ...如果你在解密数据之前不知道要阅读多少,那么知道读多少会更难。

推荐: 加密长度的4字节(还有其他方法)

读取字节,直到收到刚读取的长度。

(解密有效载荷)

4bytes ...

N字节......

(解密)

连接流时重复。


如果您可以控制加密端。

函数接收输入字节 加密返回Encypted bytes

发送加密字节长度(4字节) 发送加密字节

对每个输入块重复。