63 lines
2.0 KiB
Swift
63 lines
2.0 KiB
Swift
/**
|
|
* Author: Hugo Pointcheval
|
|
* Email: git@pcl.ovh
|
|
* -----
|
|
* File: KDF.swift
|
|
* Created Date: 25/12/2021 17:45:28
|
|
* Last Modified: 25/12/2021 17:45:38
|
|
* -----
|
|
* Copyright (c) 2021
|
|
*/
|
|
|
|
import Foundation
|
|
import CryptoKit
|
|
import CommonCrypto
|
|
|
|
class Key {
|
|
/// Generate secret key of a specified length
|
|
@available(iOS 13.0, *)
|
|
static func fromSecureRandom(bitsCount : Int) -> Data {
|
|
let symmetricKey = SymmetricKey.init(size: SymmetricKeySize(bitCount: bitsCount))
|
|
return toBytes(key: symmetricKey)
|
|
}
|
|
|
|
/// Encode key as Data
|
|
@available(iOS 13.0, *)
|
|
static func toBytes(key: SymmetricKey) -> Data {
|
|
let keyBytes = key.withUnsafeBytes
|
|
{
|
|
return Data(Array($0))
|
|
}
|
|
return keyBytes
|
|
}
|
|
|
|
/// Derive a new secret key with PBKDF2 algorithm
|
|
static func fromPBKDF2(password: String, salt: String, keyBytesCount: Int, iterations: Int, algorithm: HashAlgorithm) -> Data? {
|
|
let passwordData = password.data(using: .utf8)!
|
|
let saltData = salt.data(using: .utf8)!
|
|
|
|
var derivedKeyData = Data(repeating: 0, count: keyBytesCount)
|
|
let localDerivedKeyData = derivedKeyData
|
|
|
|
let status = derivedKeyData.withUnsafeMutableBytes { (derivedKeyBytes: UnsafeMutableRawBufferPointer) in
|
|
saltData.withUnsafeBytes { (saltBytes: UnsafeRawBufferPointer) in
|
|
CCKeyDerivationPBKDF(
|
|
CCPBKDFAlgorithm(kCCPBKDF2),
|
|
password,
|
|
passwordData.count,
|
|
saltBytes.bindMemory(to: UInt8.self).baseAddress,
|
|
saltData.count,
|
|
algorithm.commonCrypto,
|
|
UInt32(iterations),
|
|
derivedKeyBytes.bindMemory(to: UInt8.self).baseAddress,
|
|
localDerivedKeyData.count)
|
|
}
|
|
}
|
|
if (status != kCCSuccess) {
|
|
return nil;
|
|
}
|
|
|
|
return derivedKeyData
|
|
}
|
|
}
|