39 lines
1.3 KiB
Swift
39 lines
1.3 KiB
Swift
import CommonCrypto
|
|
import Foundation
|
|
|
|
enum PinHash {
|
|
private static let iterations: UInt32 = 100_000
|
|
private static let keyLength = 32 // 256 bits
|
|
|
|
static func generateSalt() -> Data {
|
|
var salt = Data(count: 16)
|
|
_ = salt.withUnsafeMutableBytes { SecRandomCopyBytes(kSecRandomDefault, 16, $0.baseAddress!) }
|
|
return salt
|
|
}
|
|
|
|
static func hash(_ input: String, salt: Data) -> String {
|
|
var derivedKey = Data(count: keyLength)
|
|
let inputData = Data(input.utf8)
|
|
|
|
_ = derivedKey.withUnsafeMutableBytes { derivedPtr in
|
|
inputData.withUnsafeBytes { inputPtr in
|
|
salt.withUnsafeBytes { saltPtr in
|
|
CCKeyDerivationPBKDF(
|
|
CCPBKDFAlgorithm(kCCPBKDF2),
|
|
inputPtr.baseAddress, inputData.count,
|
|
saltPtr.baseAddress, salt.count,
|
|
CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),
|
|
iterations,
|
|
derivedPtr.baseAddress, keyLength
|
|
)
|
|
}
|
|
}
|
|
}
|
|
return derivedKey.base64EncodedString()
|
|
}
|
|
|
|
static func verify(_ input: String, against storedHash: String, salt: Data) -> Bool {
|
|
hash(input, salt: salt) == storedHash
|
|
}
|
|
}
|