func pbkdf2SHA1(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash: CCPBKDFAlgorithm(kCCPRFHmacAlgSHA1), password: password, salt: salt, keyByteCount: keyByteCount, rounds: rounds)
func pbkdf2SHA256(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash: CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), password: password, salt: salt, keyByteCount: keyByteCount, rounds: rounds)
func pbkdf2SHA512(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash: CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512), password: password, salt: salt, keyByteCount: keyByteCount, rounds: rounds)
func pbkdf2(hash: CCPBKDFAlgorithm, password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
let passwordData = password.data(using: String.Encoding.utf8)!
var derivedKeyData = Data(repeating: 0, count: keyByteCount)
let derivedKeyDataLength = derivedKeyData.count
let derivationStatus = derivedKeyData.withUnsafeMutableBytes { derivedKeyBytes in
salt.withUnsafeBytes { saltBytes in
CCPBKDFAlgorithm(kCCPBKDF2),
password, passwordData.count,
derivedKeyBytes, derivedKeyDataLength
if derivationStatus != 0 {
func testKeyDerivation() {
let password = "password"
let salt = Data([0x73, 0x61, 0x6C, 0x74, 0x44, 0x61, 0x74, 0x61])
let derivedKey = pbkdf2SHA1(password: password, salt: salt, keyByteCount: keyByteCount, rounds: rounds)