【问题标题】:CCCrypt padding option doesn't seem to affect decryptionCCCrypt 填充选项似乎不影响解密
【发布时间】:2016-01-07 06:59:52
【问题描述】:

我有一个使用 Java 加密的字符串

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(text.getBytes());    

(注意在Java中,使用AES时PKCS5Padding实际上是PKCS7Paddinglink

而我的解密内码是:

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                      kCCAlgorithmAES128,
                                      0,
                                      key.bytes,
                                      kCCBlockSizeAES128,
                                      iv.bytes,
                                      [encrypted bytes],
                                      dataLength,
                                      buffer,
                                      bufferSize,
                                      &numBytesEncrypted);

像这样称呼:

let decryptedData = decryptor.AES128DecryptWithKeyString(key, encryptedString: encodedString) //this does the CCCrypt stuff
let string:NSString = NSString(data: decryptedData, encoding: NSUTF8StringEncoding) ?? ""
let data = NSData(base64EncodedString: string as String, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)

因此,即使它是使用 PKCS5Padding 加密的,尽管没有提供填充选项,但我的解密工作正常。此外,如果我将0 选项更改为kCCOptionPKCS7Padding,它也可以解密。

这是预期的行为吗?填充选项是否仅与 kCCEncrypt 相关而不与 kCCDecrypt 相关?

另外,如果我们将Java加密改为

Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");

并用零字节手动填充有效负载,然后无论我使用0作为选项还是kCCOptionPKCS7Padding,它仍然可以正确解密

【问题讨论】:

    标签: ios encryption commoncrypto


    【解决方案1】:

    当您说填充不影响解密时,您是在查看十六进制转储中的输出吗?

    填充将是 0x010x10 范围内的尾随字符,它们是非打印 ASCII 字符,因此在打印使用 PKCS#7 填充加密但使用填充解密的字符串时,它可能看起来相同选项。

    将示例输出作为十六进制转储添加到问题中,您应该会看到实际发生了什么。

    返回状态不表示正确解密或无效填充,仅表示严重调用错误。

    例子:

    let keyData     = Array("12345678901234567890123456789012".utf8)
    let messageData = Array("Don´t try".utf8)
    
    let encrypted = testCrypt(data:messageData, keyData:keyData, operation:kCCEncrypt, options:UInt32(kCCOptionPKCS7Padding))!
    print("encrypted:       \(encrypted)")
    
    let decryptedPKCS7 = testCrypt(data:encrypted, keyData:keyData, operation:kCCDecrypt, options:UInt32(kCCOptionPKCS7Padding))!
    print("decrypted PKCS7: \(decryptedPKCS7)")
    
    let decryptedNone = testCrypt(data:encrypted, keyData:keyData, operation:kCCDecrypt, options:UInt32(0))!
    print("decrypted None:  \(decryptedNone)")
    

    输出:

    加密:[136、95、194、76、137、107、196、39、245、108、106、84、139、49、14、139] 解密的 PKCS7:[68、111、110、194、180、116、32、116、114、121] 解密无:[68, 111, 110, 194, 180, 116, 32, 116, 114, 121, 6, 6, 6, 6, 6, 6]

    尾随的六个 0x06 字节是未删除的填充。

    【讨论】:

    • 我正在查看 NSData 并将其转换为 UIImage,并且它可以正常显示。
    • 当我没有指定 kCCOptionPKCS7Padding 时,我在 NSData 上看到了额外的填充字节,但我很困惑为什么在将其转回 UIImage let data = NSData(base64EncodedString: string as String, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) 填充的 base64 编码数据时字节消失。 (即使没有 IgnoreUnknownCharacters 选项,它们也会消失)
    • 由于数据无效(包含填充字符),操作未定义。
    猜你喜欢
    • 1970-01-01
    • 2012-08-14
    • 2013-08-12
    • 2013-06-28
    • 2012-01-03
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 2012-10-27
    相关资源
    最近更新 更多