我已经设法使用模块映射让CommonCrypto在Swift中工作,但有人可以告诉我使用CommonCrypto在Swift 2中使用PBKDF2进行散列的代码
解决方法
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 }
hash是哈希类型,例如kCCPRFHmacAlgSHA1,kCCPRFHmacAlgSHA256,kCCPRFHmacAlgSHA512.
日落文档部分的示例:
基于密码的密钥派生2(Swift 3)
基于密码的密钥派生既可用于从密码文本中导出加密密钥,也可用于保存密码以进行身份验证.
可以使用几种哈希算法,包括SHA1,SHA256,SHA512,这些算法由此示例代码提供.
rounds参数用于使计算变慢,以便攻击者必须在每次尝试上花费大量时间.典型的延迟值在100ms到500ms之间,如果有不可接受的性能,可以使用更短的值.
此示例需要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,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,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,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>
基于密码的密钥派生校准
此示例需要Common Crypto
有必要为项目建立一个桥接头:
#import <CommonCrypto/CommonCrypto.h>
确定当前平台上特定延迟使用的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.
Password Based Key Derivation Calibration (Swift 3)
func pbkdf2SHA1Calibrate(password: String,msec: Int) -> UInt32 { let actualRoundCount: UInt32 = CCCalibratePBKDF( CCPBKDFAlgorithm(kCCPBKDF2),password.utf8.count,CcpseudoRandomAlgorithm(kCCPRFHmacAlgSHA1),kCCKeySizeAES256,UInt32(msec)); return actualRoundCount }
用法示例:
let saltData = Data(bytes: [0x73,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
Password Based Key Derivation Calibration (Swift 2.3)
func pbkdf2SHA1Calibrate(password:String,salt:[UInt8],msec:Int) -> UInt32 { let actualRoundCount: UInt32 = CCCalibratePBKDF( CCPBKDFAlgorithm(kCCPBKDF2),UInt32(msec)); return actualRoundCount }
用法示例:
let saltData = [UInt8]([0x73,0x61]) let passwordString = "password" let delayMsec = 100 let rounds = pbkdf2SHA1Calibrate(passwordString,rounds: \(rounds)")
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。