有一个(相当复杂的)应用程序在 iOS 4 上运行良好,但在 iOS 5 上因解密问题而失败。它正在解密一个 SQLite DB 页面,最后 16 个字节似乎没有被正确解密。
这是否与任何人敲响警钟?
更新
我已经确定,当 CCCryptorUpdate 的缓冲区长度为 1008 (1024 - 16) 时,它只解密 992 个字节(如 dataOutMoved 参数中所述)。如果 CCCryptorFinal 返回剩余的字节,这将是可以的,但它报告移动的字节为零。然而,CCCryptorFinal 报告了一个 -4304 返回码(这是一个无用的 kCCDecodeError)。
更新 2
我已经非常确定它是一个彻头彻尾的错误。我逐字节比较了加密的输出和解密的输入,并比较了密钥。完全相同的。但是,如果缓冲区长度为 1008,那么解密总是会失败,即使给解密器提供了更大的输出缓冲区(它说在这种情况下它需要 1024)。我认为它适用于 1024,虽然我还没有通过第一个奇怪大小的缓冲区来告诉我。
ETC
好吧,似乎没有什么可以解密。这是使用“一体式”CCCrypt() 接口,该接口消除了 CCCryptorCreate/Update/Final 排序过程中出现任何错误的可能性。我想知道这是否是AES128的问题?
奇怪的是,当数据库的第 1 页被加密时,加密总是报告比我告诉它的移动多 16 个字节——如果我告诉它 1008 它报告 1024,如果我告诉它 1024 它报告 1040。没有其他页面这样做,我不明白 CCCrypt 如何知道它正在处理的页面。就像我说的,好奇。
找到了(我认为)
旧代码指定kCCOptionPKCS7Padding
,据我了解,它仅应用于加密缓冲区长度不是块长度倍数的情况(并且提供了额外的输出缓冲区空间)。这导致几乎所有解密操作都以 -4304 失败。但是在 iOS 4 中,操作仍然会移动他们解密的数据(基本上就是全部),而 iOS 5 发生了变化,如果操作失败,所有数据移动都会被抑制(最后一个块几乎总是会失败)。
关闭填充选项可使代码正常工作而不会发布任何错误。