Swift:如何从Swift调用CCKeyDerivationPBKDF

Swift:如何从Swift调用CCKeyDerivationPBKDF,第1张

Swift:如何从Swift调用CCKeyDerivationPBKDF 斯威夫特3:

基于密码的密钥派生既可以用于从密码文本派生加密密钥,又可以保存密码以进行身份​​验证。

示例代码提供了多种可用的哈希算法,包括SHA1,SHA256,SHA512。

rounds参数用于使计算变慢,因此攻击者将不得不在每次尝试上花费大量时间。典型的延迟值介于100ms至500ms之间,如果性能不可接受,则可以使用更短的值。

此示例需要通用加密
。必须在项目中具有桥接头:

#import <CommonCrypto/CommonCrypto.h>

将添加
Security.framework
到项目中。


参数:

password     password String  salt         salt Data  keyByteCount number of key bytes to generaterounds       Iteration roundsreturns      Derived keyfunc 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 = 16let rounds       = 100000let derivedKey = pbkdf2SHA1(password:password, salt:salt, keyByteCount:keyByteCount, rounds:rounds)print("derivedKey (SHA1): (derivedKey! as NSData)")

示例输出:

derivedKey (SHA1): <6b9d4fa3 0385d128 f6d196ee 3f1d6dbf>

Swift 2.x:

参数类型和类对实例方法的微小更改,以进行测试。

func generateAesKeyForPassword(password: String, salt: NSData, roundCount: Int?, error: NSErrorPointer) -> (key: NSData, actualRoundCount: UInt32)?{    let nsDerivedKey = NSMutableData(length: kCCKeySizeAES256)    var actualRoundCount: UInt32    // Create Swift intermediates for clarity in function calls    let algorithm: CCPBKDFAlgorithm        = CCPBKDFAlgorithm(kCCPBKDF2)    let prf:       CCPseudoRandomAlgorithm = CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256)    let saltBytes  = UnsafePointer<UInt8>(salt.bytes)    let saltLength = size_t(salt.length)    let nsPassword        = password as NSString    let nsPasswordPointer = UnsafePointer<Int8>(nsPassword.cStringUsingEncoding(NSUTF8StringEncoding))    let nsPasswordLength  = size_t(nsPassword.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))    var nsDerivedKeyPointer = UnsafeMutablePointer<UInt8>(nsDerivedKey.mutableBytes)    let nsDerivedKeyLength = size_t(nsDerivedKey.length)    let msec: UInt32 = 300    if roundCount != nil {        actualRoundCount = UInt32(roundCount!)    }    else {        actualRoundCount = CCCalibratePBKDF( algorithm, nsPasswordLength, saltLength, prf, nsDerivedKeyLength, msec);    }    let result = CCKeyDerivationPBKDF(        algorithm,        nsPasswordPointer,   nsPasswordLength,        saltBytes,saltLength,        prf,      actualRoundCount,        nsDerivedKeyPointer, nsDerivedKeyLength)    if result != 0 {        let errorDescription = "CCKeyDerivationPBKDF failed with error: '(result)'"        // error.memory = MyError(domain: ClientErrorType.errorDomain, pre: Int(result), descriptionText: errorDescription)        return nil    }    return (nsDerivedKey, actualRoundCount)}

//增加了奖励:

func salt(#length:UInt) -> NSData {    let salt        = NSMutableData(length: Int(length))    var saltPointer = UnsafeMutablePointer<UInt8>(salt.mutableBytes)    SecRandomCopyBytes(kSecRandomDefault, length, saltPointer);    return salt}

//测试电话:

let password   = "test pass"let salt       = self.salt(length:32)let roundCount = 300var error: NSError?let result = self.generateAesKeyForPassword(password, salt:salt, roundCount:roundCount, error:&error)println("result: (result)")

输出:

result: Optional((<d279ab8d 8ace67b7 abec844c b9979d20 f2bb0a7f 5af70502 085bf1e4 1016b20c>, 300))


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5087258.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-16
下一篇 2022-11-16

发表评论

登录后才能评论

评论列表(0条)

保存