I'm developing an iOS application in Swift and need to encrypt some text, and want to use the user password as the encryption key.
To be able to do so securely, I need to derive a symmetric key from the user password using the PBKDF2 algorithm. The problem I'm finding is that the CryptoKit framework does not provide support for such algorithm, so I use the CommonCrypto framework for deriving the key and CryptoKit for encrypting, but I'm always getting a CryptoKit.CryptoKitError.incorrectKeySize error when calling the seal method.
My code is the following:
let derivedKey: [UInt8] = PBKDF.deriveKey(password: password, salt: salt, prf: PBKDF.PseudoRandomAlgorithm.sha256, rounds: 320000, derivedKeyLength: 256)
let keyAsData = Data(derivedKey)
let nonce = AES.GCM.Nonce()
let key = SymmetricKey(data: keyAsData)
let sealedBox = try AES.GCM.seal(data, using: key, nonce: nonce)
The method PBKDF.deriveKey coms from the IDZSwiftCommonCrypto project which is a wrapper around CommonCrypto in Swift.
If I create the key with let key = SymmetricKey(size: .bits256)
, then the encryption works fine, so I there is a problem with the way I'm creating the key.
Should I be creating the key differently?
The derivedKeyLength
parameter to PBKDF.deriveKey
is in bytes. You've passed bits. You want to pass 32 here, not 256. (This is a very common mistake in cryptographic work. The tools are not very consistent about whether they are working on bits or bytes.)
I believe the code you want here is:
let derivedKey = PBKDF.deriveKey(password: password,
salt: salt,
prf: .sha256,
rounds: 320_000,
derivedKeyLength: 32)
let sealedBox = try AES.GCM.seal(data, using: SymmetricKey(data: derivedKey))
You can get the nonce from the sealedBox
, which will automatically make a random one, so there's no need for the extra steps.