2017-10-28 170 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