2016-10-31 24 views
1

我试图用CommonCrypto哈希使用PBKDF2密码斯威夫特2,因为它的高性能,也由于它是开源的如何斯威夫特使用CommonCrypto为PBKDF2 2

我已经设法获得CommonCrypto在斯威夫特工作使用模块的地图,但有人可以告诉我的代码使用CommonCrypto

任何帮助是非常赞赏:)感谢斯威夫特2 PBKDF2哈希!

回答

2
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是哈希类型如kCCPRFHmacAlgSHA1kCCPRFHmacAlgSHA256kCCPRFHmacAlgSHA512。从已停用文档部分

实施例:

基于密码密钥导出2(SWIFT 3+)

基于密码密钥导出可用于从密码文本的加密密钥和保存密码被用于既用于验证目的。

存在可以包括SHA1,SHA256,SHA512其通过本实施例中提供代码可以使用几个散列算法。

的轮参数是用来进行计算缓慢,攻击者将不得不花费大量的时间在每次尝试。典型的延迟值在100毫秒降至500毫秒,如果存在不可接受的性能更短的值都可以使用。

这个例子需要公共的密码
这是需要有一个桥接报的项目:
#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> 

基于密码密钥导出校准

此示例要求公共密码 这是需要有一个桥接报的项目:

#import <CommonCrypto/CommonCrypto.h> 

添加Security.framework到项目中。


确定当前平台上用于特定延迟的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. 

基于密码密钥导出校准(SWIFT 3)

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 

基于密码密钥导出校准(SWIFT 2.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)")