【问题标题】:Encrypting 16 bytes of UTF8 with SecKeyWrapper breaks (ccStatus == -4304)使用 SecKeyWrapper 中断加密 16 字节的 UTF8 (ccStatus == -4304)
【发布时间】:2011-05-04 13:24:17
【问题描述】:

我正在使用 Apple 文档中 CryptoExercise 示例代码中的 Apple 的 SecKeyWrapper 类来使用 AES128 进行一些对称加密。出于某种原因,当我加密 1-15 个字符或 17 个字符时,它会正确加密和解​​密。使用 16 个字符,我可以加密,但在解密时,它会在使用 ccStatus == -4304 调用 CCCryptorFinal 后引发异常,这表示解码错误。 (上图。)

我了解 AES128 每个加密块使用 16 个字节,因此我认为该错误与落在块边界上的明文长度有关。有没有人使用CommonCryptorSecKeyWrapper 遇到这个问题?

【问题讨论】:

    标签: iphone ios aes


    【解决方案1】:

    以下几行...

    // We don't want to toss padding on if we don't need to
    if (*pkcs7 != kCCOptionECBMode) {
      if ((plainTextBufferSize % kChosenCipherBlockSize) == 0) {
    *pkcs7 = 0x0000;
      } else {
        *pkcs7 = kCCOptionPKCS7Padding;
      }
    }
    

    ... 是我的问题的罪魁祸首。为了解决这个问题,我只需将它们注释掉即可。

    据我所知,加密过程不是在加密端进行填充,而是在解密端仍然期待填充,导致解密过程失败(这通常是我遇到的情况)。

    到目前为止,对于满足 length % 16 == 0 和不满足的字符串,始终使用 kCCOptionPKCS7Padding 加密/解密对我有用。同样,这是对CryptoExercise 示例 代码的SecKeyWrapper 类的修改。不确定这对使用 CommonCrypto 和自制包装器的用户有何影响。

    【讨论】:

    • 请注意,任何犯了这种基本错误的密码库都不应该被使用。应始终应用填充,以便您可以看到哪些字节是填充,哪些字节是纯数据。不填充分组密码的唯一原因是当您通过其他方式知道消息长度时。
    【解决方案2】:

    我在使用 CommonCrypto 类时也遇到过这个问题,但对于长度为 16 的倍数的任何字符串。

    我的解决方案完全是 hack,因为我还没有找到真正的解决方案。

    如果字符串是 16 的倍数,我会在最后用空格填充字符串。它适用于我的特定场景,因为数据上的额外空间不会影响另一侧数据的接收,但我对此表示怀疑适用于其他任何人的场景。

    希望更聪明的人可以为我们指明正确的方向,找到真正的解决方案。

    【讨论】:

    • 始终保持填充是解决方案。没有办法检测是否添加了填充,除非您的数据不以值 1..16 结尾并且您编写自己的加密例程来检查这一点(但这不应该这样做)。
    猜你喜欢
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多