2

我想在 Swift 中使用 aes-128-ctr 和 CryptoSwift 库,但是我得到的密文太长了。

我的 IV 是 16 字节,盐是 32 字节,aes 明文也是 32 字节,为什么得到的密文是 48 字节,因此又填充了 16 字节?

let salt: [UInt8] = Array("tkmlidnonknkqgvapjrpdcductebsozn".utf8) 
let derivedKey = try PKCS5.PBKDF2(password: password, salt: salt, iterations: numberOfIterations, variant: .sha256).calculate()
let iv: [UInt8] = Array("abcdefgthksdfghj".utf8)
let aesKey: [UInt8] = Array(derivedKey[..<16])
let aes = try AES(key: aesKey, blockMode: .CTR(iv: iv))
let ciphertext = try aes.encrypt(password)

这里的密码是提到的 32 字节明文。

另外,有没有办法生成随机盐?我找到

let iv: [UInt8] = AES.randomIV(AES.blockSize)

生成一个随机 IV,但是我如何获得这样的盐?

4

1 回答 1

2

根据CryptoSwift 文档,它默认使用 PKCS7 填充。由于 CTR 模式不需要填充,您可以(并且应该)通过添加padding: .noPadding到您的AES()构造函数调用来禁用它。

对 PBKDF2 salt 没有特殊的格式要求(它实际上可以是任何随机字节串),因此您应该能够使用AES.randomIV()(或任何其他随机字节源)来生成一个。

在内部,CryptoSwiftAES.randomIV()代码似乎使用了 RandomBytesSequence,但不幸的是,CryptoSwitf 的那部分似乎没有记录。除了randomIV()源代码本身之外,我能找到的唯一使用示例就是这个测试用例。顺便说一句,看起来真的很糟糕单元测试——它似乎只是在测试一个AnyIterator<UInt8>实际返回UInt8的值。它甚至没有检查迭代器是否实际返回了请求的字节数,它可能完全无法做到这一点,例如,如果/dev/urandom由于某种原因打开失败。)

于 2017-10-28T20:29:12.343 回答