2017-10-28 172 views
2

我想在CryptoSwift库中使用Swift中的aes-128-ctr,但是由此产生的密文太长。Swift - AES 128 ctr,密文太长

我的IV是16字节,salt 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,但是我怎么得到这样的盐?

+2

它是最好避免使用CryptoSwift,其他的事情比基于Common Crypto的实现慢500到1000倍。 Apple的Common Crypto已通过FIPS认证,并且经过充分审查,使用CryptoSwift正在考虑正确性和安全性。 – zaph

回答

2

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

上有PBKDF2盐没有特殊的格式要求(也可以是字节字面上任何随机字符串),所以你应该能够使用AES.randomIV()(或随机字节的任何其他来源)来生成一个。

Internally,则CryptoSwift AES.randomIV()代码似乎使用RandomBytesSequence,但CryptoSwitf的不幸的一部分似乎是无证,唯一使用的例子,我能找到的,除了randomIV()源代码本身,是this test case。其中,顺便说一句,看起来像一个非常糟糕的单元测试—所有它似乎测试的是,AnyIterator<UInt8>实际上返回UInt8值。它甚至不检查迭代器实际返回所请求的字节数,它可能完全无法做到,例如,如果打开/dev/urandom由于某种原因失败)。

+2

另外,我想指出的是,我同意上面的zaph的评论:如果您可以选择使用官方认证的加密库,那么您可能应该这么做。它不能保证你的代码是安全的,但它会确保它的任何安全漏洞都是你自己的错。 ;) –

+0

谢谢你的回答,解决了这个问题,我会尝试切换到一个认证的库建议 – phoebus

+1

我觉得奇怪的是,应该有必要设置CTR模式的任何一种填充少于设置为'。 noPadding“,这应该是CTR模式的默认值。我还发现,如果Apple没有更新Common Crypto或者由于缺少SHA-3,Argon2和AES GCM模式而更换它,更不用说Crypto和Swift组织之间的争执了。 – zaph