我正在尝试从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)
}
let passwordData = password.data(using:String.Encoding.utf8)!
不再是必需的。当您将SwiftString
传递给类型为UnsafePointer<Int8>!
的参数时,编译器会自动为您执行此操作,并确保生成的对象在C函数返回前保持活动状态。也不需要桥接头文件,import CommonCrypto
可以正常工作。 - Mecki