带AES128 CTR模式的CryptoSwift-小车计数器增量?

带AES128 CTR模式的CryptoSwift-小车计数器增量?,swift,encryption,aes,cryptoswift,Swift,Encryption,Aes,Cryptoswift,我在CTR模式下使用AES128时,在CryptoSwift API(krzyzanowskim)上遇到了一个问题,我的测试函数(nullArrayBugTest())在特定计数器值上产生了一个错误的数组计数,通常应该是16! 即使我使用手动递增的“iv_13”和错误值13,而不是默认的“iv_0”和计数器13。。。 测试一下,了解我的意思 func nullArrayBugTest() { var ctr:CTR let nilArrayToEncrypt = Data(h

我在
CTR模式下使用
AES128
时,在
CryptoSwift API(krzyzanowskim)
上遇到了一个问题,我的测试函数
(nullArrayBugTest())
在特定计数器值上产生了一个错误的数组计数,通常应该是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)")
        }
    }
}
func nullArrayBugTest(){
风险中心:风险中心
让nilArrayToEncrypt=数据(十六进制:“00000000000000000000000000”)
让键=数据(十六进制:“000a0b0c0d0e0f010203040506070809”)
设iv_0:Array=[0x00、0x01、0x02、0x03、0x04、0x05、0x06、0x07、0x08、0x09、0x0a、0x0b、0x0c、0x0d、0x0e、0x0f]
//设iv_13:Array=[0x00、0x01、0x02、0x03、0x04、0x05、0x06、0x07、0x08、0x09、0x0a、0x0b、0x0c、0x0d、0x0e、0x1c]
var decryptedNilArray=[UInt8]()
因为我在0…25{
ctr=ctr(iv:iv_0,计数器:i)
做{
让aes=尝试aes(键:键字节,块模式:ctr)
decryptedNilArray=尝试aes.decrypt([UInt8](nilArrayToEncrypt))
打印(“AES_测试用例(i)用于ctr:\(ctr)和ArrayCount:\(decryptedNilArray.count)”)
}抓住{
打印(“反/加密数据失败,错误:\”)
}
}
}

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

有人知道为什么aes.decrypt()函数会像我收到的那样处理这个问题吗

谢谢你抽出时间


Michael S.

CryptoSwift默认为PKCS#7填充。生成的明文具有无效的填充。哪个IMO是一个bug,但它就是这样实现的。(您认为“正确”的所有计数器都应该根本无法解密。)(我与Marcin讨论了这一点,他提醒我,即使在这么低的级别上,忽略填充错误以避免填充oracle攻击也是正常的。)

也就是说,有时填充将“足够接近”,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)