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));

…我得到这个编译器错误:

无法使用类型为’(CCPBKDFAlgorithm,UnsafePointer,size_t,UnsafePointer,size_t,CCPseudoRandomAlgorithm,uint,UnsafeMutablePointer,size_t)的参数列表调用’init’

我相信所有强制转换都是正确的(实际上,编译器错误帮助我识别了每个参数的每个问题)-这使我认为编译器理解了我调用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), CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256), UInt(derivedKey.length), UInt32(300) /* milliseconds */));

}

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));

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)

}

回答:

回答:

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

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

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

此示例需要通用加密

。必须在项目中具有桥接头:

#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>


回答:

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

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, code: 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 = 300

var 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))

以上是 Swift:如何从Swift调用CCKeyDerivationPBKDF 的全部内容, 来源链接: utcz.com/qa/403781.html

回到顶部