Swift:如何从Swift调用CCKeyDerivationPBKDF
我正试图从Swift调用CCKeyDerivationPBKDF.
我在Project-Bridging-Header.h中导入了所需的标题: #import <CommonCrypto/CommonKeyDerivation.h> (顺便说一下,桥接头似乎可以正常导入我项目中的其他Objective C代码). 在Xcode中,我可以从我的.swift文件跳转到这里显示的定义: int CCKeyDerivationPBKDF( CCPBKDFAlgorithm algorithm,const char *password,size_t passwordLen,const uint8_t *salt,size_t saltLen,CCPseudoRandomAlgorithm prf,uint rounds,uint8_t *derivedKey,size_t derivedKeyLen) 最后,当我尝试这样调用函数时: let result = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),NSString(password).UTF8String,size_t(passwordLength),UnsafePointer<UInt8>(salt.bytes),size_t(salt.length),CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),uint(actualRoundCount),UnsafeMutablePointer<UInt8>(derivedKey.mutableBytes),size_t(derivedKey.length)); …我得到这个编译器错误:
我相信所有演员阵容都是正确的(实际上编译器错误帮助我识别每个参数的每个问题) – 这让我觉得编译器理解我调用CCKeyDerivationPBKDF的意图. 然而,在所有其他转换错误消失后,编译器感到困惑,并认为我正在尝试使用初始化程序构造一个类. 希望有人能告诉我我的方式的错误. (Xcode 6 beta 7) 根据要求,上下文中的完整代码: class func generateAesKeyForPassword(password: String,salt: NSData,roundCount: UInt?,error: NSErrorPointer) -> (key: NSData,actualRoundCount: UInt)? { let derivedKey = NSMutableData(length: kCCKeySizeAES256) let passwordLength = size_t(password.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)) var actualRoundCount: UInt if roundCount != nil { actualRoundCount = roundCount! } else { actualRoundCount = UInt(CCCalibratePBKDF(CCPBKDFAlgorithm(kCCPBKDF2),passwordLength,UInt(salt.length),UInt(derivedKey.length),UInt32(300) /* milliseconds */)); } let result = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),size_t(derivedKey.length)); if result != 0 { let errorDescription = "CCKeyDerivationPBKDF failed with error: '(result)'" error.memory = MyError(domain: ClientErrorType.errorDomain,code: Int(result),descriptionText: errorDescription) return nil } return (NSData(data: derivedKey),actualRoundCount) }
斯威夫特3:
基于密码的密钥派生既可用于从密码文本中导出加密密钥,也可用于保存密码以进行身份??验证. 可以使用几种哈希算法,包括SHA1,SHA256,SHA512,这些算法由此示例代码提供. rounds参数用于使计算变慢,以便攻击者必须在每次尝试上花费大量时间.典型的延迟值在100ms到500ms之间,如果有不可接受的性能,可以使用更短的值. 此示例需要Common Crypto 参数: 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,rounds: Int) -> Data? { return pbkdf2(hash:CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256),rounds:rounds) } func pbkdf2SHA512(password: String,rounds: Int) -> Data? { return pbkdf2(hash:CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512),rounds:rounds) } func pbkdf2(hash :CCPBKDFAlgorithm,password: String,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]) let keyByteCount = 16 let rounds = 100000 let derivedKey = pbkdf2SHA1(password:password,rounds:rounds) print("derivedKey (SHA1): (derivedKey! as NSData)") 示例输出: derivedKey (SHA1): <6b9d4fa3 0385d128 f6d196ee 3f1d6dbf> Swift 2.x: 参数类型和类的微小更改以及测试的实例方法. func generateAesKeyForPassword(password: String,roundCount: Int?,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,actualRoundCount,nsDerivedKeyPointer,nsDerivedKeyLength) if result != 0 { let errorDescription = "CCKeyDerivationPBKDF failed with error: '(result)'" // error.memory = MyError(domain: ClientErrorType.errorDomain,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 = 300 var error: NSError? let result = self.generateAesKeyForPassword(password,roundCount:roundCount,error:&error) println("result: (result)") 输出: result: Optional((<d279ab8d 8ace67b7 abec844c b9979d20 f2bb0a7f 5af70502 085bf1e4 1016b20c>,300)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |