加密雨燕与AES128 CTR模式 - 错误的计数器增量?



我在CryptoSwift-API (krzyzanowskim)上遇到了一个问题,同时将AES128CTR-Mode一起使用,我的测试函数(nullArrayBugTest())在特定计数器值(0 到 25 之间 = 13 和 24 之间(产生错误的数组计数,通常应该是 16! 即使我使用手动递增的"iv_13"错误值 13 而不是默认的"iv_0"和计数器 13...... 测试一下以了解我的意思。

func nullArrayBugTest() {
var ctr:CTR
let nilArrayToEncrypt = Data(hex: "00000000000000000000000000000000")
let key_ = Data(hex: "000a0b0c0d0e0f010203040506070809")
let iv_0:  Array<UInt8> = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]
//let iv_13:  Array<UInt8> = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x1c]
var decryptedNilArray = [UInt8]()
for i in 0...25 {
ctr = CTR(iv: iv_0, counter: i)
do {
let aes = try AES(key: key_.bytes, blockMode: ctr)
decryptedNilArray = try aes.decrypt([UInt8](nilArrayToEncrypt))
print("AES_testcase_(i) for ctr: (ctr) withArrayCount: (decryptedNilArray.count)")
}catch {
print("De-/En-CryptData failed with: (error)")
}
}
}

带有错误值的输出

为什么我总是需要具有 16 个值的加密数组的问题并不重要:D。

有谁知道为什么aes.decrypt()函数像我收到的那样处理?

谢谢你的时间。

迈克尔·

CryptoSwift 默认为 PKCS#7 填充。生成的明文具有无效的填充。CryptoSwift忽略了填充错误,IMO是一个错误,但这就是它的实现方式。(您认为"正确"的所有计数器实际上应该根本无法解密。(我和Marcin谈过这个问题,他提醒我,即使在这个低级别,忽略填充错误以避免填充预言机攻击也是正常的。我忘了我也是这样做的...

也就是说,有时填充会"足够接近",以至于CryptoSwift会尝试删除填充字节。它通常不会是有效的填充,但它对于CrypoSwift的测试来说已经足够接近了。

例如,您的第一个计数器创建以下填充的纯文本:

[233, 222, 112, 79, 186, 18, 139, 53, 208, 61, 91, 0, 120, 247, 187, 254]

254> 16,所以 CryptoSwift 不会尝试删除填充。

对于计数器 13,返回以下填充的纯文本:

[160, 140, 187, 255, 90, 209, 124, 158, 19, 169, 164, 110, 157, 245, 108, 12]

12 <16,因此 CryptoSwift 删除了 12 个字节,留下 4 个字节。(这不是PKCS#7填充的工作方式,但这是CryptoSwift的工作方式。

根本问题是你没有解密你加密的东西。您只是通过解密方案运行静态块。

如果您不需要填充,可以请求:

let aes = try AES(key: key_.bytes, blockMode: ctr, padding: .noPadding)

这将返回您期望的内容。

以防万一其他读者有任何混淆:CTR的这种使用非常不安全,不应复制其中的任何部分。我假设实际的加密代码不能像这样工作。

我想加密是在没有应用填充的情况下发生的,但随后您使用填充来解密。要解决此问题,请在两边使用相同的技术。也就是说,这是一个解决方案(@rob-napier答案更详细(:

try AES(key: key_.bytes, blockMode: ctr, padding: .noPadding)

最新更新