Enric
Enric

Reputation: 195

How to use PBKDFD2 with CryptoKit

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?

Upvotes: 4

Views: 317

Answers (1)

Rob Napier
Rob Napier

Reputation: 299265

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.

Upvotes: 3

Related Questions