Swift Language
Вывод ключа PBKDF2
Поиск…
Основанный на пароле вывод 2 (Swift 3)
Деривация ключа на основе пароля может использоваться как для получения ключа шифрования из текста пароля, так и для сохранения пароля для целей аутентификации.
Существует несколько алгоритмов хэширования, которые могут использоваться, включая SHA1, SHA256, SHA512, которые предоставляются этим примером кода.
Параметр rounds используется для того, чтобы сделать расчет медленным, чтобы злоумышленник должен был тратить значительное время на каждую попытку. Типичные значения задержки падают в диапазоне от 100 мс до 500 мс, более короткие значения могут использоваться, если есть неприемлемая производительность.
Этот пример требует Common Crypto
Необходимо иметь заголовок заголовка проекта:
#import <CommonCrypto/CommonCrypto.h>
Добавьте в проект Security.framework
.
Параметры:
password password String
salt salt Data
keyByteCount number of key bytes to generate
rounds Iteration rounds
returns Derived key
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 derivationStatus = derivedKeyData.withUnsafeMutableBytes {derivedKeyBytes in
salt.withUnsafeBytes { saltBytes in
CCKeyDerivationPBKDF(
CCPBKDFAlgorithm(kCCPBKDF2),
password, passwordData.count,
saltBytes, salt.count,
hash,
UInt32(rounds),
derivedKeyBytes, derivedKeyData.count)
}
}
if (derivationStatus != 0) {
print("Error: \(derivationStatus)")
return nil;
}
return derivedKeyData
}
Пример использования:
let password = "password"
//let salt = "saltData".data(using: String.Encoding.utf8)!
let salt = Data(bytes: [0x73, 0x61, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61])
let keyByteCount = 16
let rounds = 100000
let derivedKey = pbkdf2SHA1(password:password, salt:salt, keyByteCount:keyByteCount, rounds:rounds)
print("derivedKey (SHA1): \(derivedKey! as NSData)")
Пример:
derivedKey (SHA1): <6b9d4fa3 0385d128 f6d196ee 3f1d6dbf>
Вывод пароля на основе пароля 2 (Swift 2.3)
См. Пример Swift 3 для использования информации и заметок
func pbkdf2SHA1(password: String, salt: [UInt8], keyCount: Int, rounds: Int) -> [UInt8]? {
return pbkdf2(CCPBKDFAlgorithm(kCCPRFHmacAlgSHA1), password:password, salt:salt, keyCount:keyCount, rounds:UInt32(rounds))
}
func pbkdf2SHA256(password: String, salt: [UInt8], keyCount: Int, rounds: Int) -> [UInt8]? {
return pbkdf2(CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), password:password, salt:salt, keyCount:keyCount, rounds:UInt32(rounds))
}
func pbkdf2SHA512(password: String, salt: [UInt8], keyCount: Int, rounds: Int) -> [UInt8]? {
return pbkdf2(CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512), password:password, salt:salt, keyCount:keyCount, rounds:UInt32(rounds))
}
func pbkdf2(hash :CCPBKDFAlgorithm, password: String, salt: [UInt8], keyCount: Int, rounds: UInt32!) -> [UInt8]! {
let derivedKey = [UInt8](count:keyCount, repeatedValue:0)
let passwordData = password.dataUsingEncoding(NSUTF8StringEncoding)!
let derivationStatus = CCKeyDerivationPBKDF(
CCPBKDFAlgorithm(kCCPBKDF2),
UnsafePointer<Int8>(passwordData.bytes), passwordData.length,
UnsafePointer<UInt8>(salt), salt.count,
CCPseudoRandomAlgorithm(hash),
rounds,
UnsafeMutablePointer<UInt8>(derivedKey),
derivedKey.count)
if (derivationStatus != 0) {
print("Error: \(derivationStatus)")
return nil;
}
return derivedKey
}
Пример использования:
let password = "password"
// let salt = [UInt8]("saltData".utf8)
let salt = [UInt8]([0x73, 0x61, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61])
let rounds = 100_000
let keyCount = 16
let derivedKey = pbkdf2SHA1(password, salt:salt, keyCount:keyCount, rounds:rounds)
print("derivedKey (SHA1): \(NSData(bytes:derivedKey!, length:derivedKey!.count))")
Пример:
derivedKey (SHA1): <6b9d4fa3 0385d128 f6d196ee 3f1d6dbf>
Калибровка вывода ключа на основе пароля (Swift 2.3)
См. Пример Swift 3 для использования информации и заметок
func pbkdf2SHA1Calibrate(password:String, salt:[UInt8], msec:Int) -> UInt32 {
let actualRoundCount: UInt32 = CCCalibratePBKDF(
CCPBKDFAlgorithm(kCCPBKDF2),
password.utf8.count,
salt.count,
CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1),
kCCKeySizeAES256,
UInt32(msec));
return actualRoundCount
}
Пример использования:
let saltData = [UInt8]([0x73, 0x61, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61])
let passwordString = "password"
let delayMsec = 100
let rounds = pbkdf2SHA1Calibrate(passwordString, salt:saltData, msec:delayMsec)
print("For \(delayMsec) msec delay, rounds: \(rounds)")
Пример:
За 100 мс задержка, раунды: 94339
Калибровка вывода ключа на основе пароля (Swift 3)
Определите количество раундов PRF для использования для определенной задержки на текущей платформе.
Несколько параметров дефолтны для репрезентативных значений, которые не должны существенно влиять на количество раундов.
password Sample password.
salt Sample salt.
msec Targeted duration we want to achieve for a key derivation.
returns The number of iterations to use for the desired processing time.
func pbkdf2SHA1Calibrate(password: String, salt: Data, msec: Int) -> UInt32 {
let actualRoundCount: UInt32 = CCCalibratePBKDF(
CCPBKDFAlgorithm(kCCPBKDF2),
password.utf8.count,
salt.count,
CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1),
kCCKeySizeAES256,
UInt32(msec));
return actualRoundCount
}
Пример использования:
let saltData = Data(bytes: [0x73, 0x61, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61])
let passwordString = "password"
let delayMsec = 100
let rounds = pbkdf2SHA1Calibrate(password:passwordString, salt:saltData, msec:delayMsec)
print("For \(delayMsec) msec delay, rounds: \(rounds)")
Пример:
For 100 msec delay, rounds: 93457