Swift:如何从Swift调用CCKeyDerivationPBKDF

Swift:如何从Swift调用CCKeyDerivationPBKDF,第1张

概述我正试图从Swift调用CCKeyDerivationPBKDF. 我在Project-Bridging-Header.h中导入了所需的标题: #import <CommonCrypto/CommonKeyDerivation.h> (顺便说一下,桥接头似乎可以正常导入我项目中的其他Objective C代码). 在Xcode中,我可以从我的.swift文件跳转到这里显示的定义: int CCK 我正试图从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));

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

Cannot invoke ‘init’ with an argument List of type ‘(CCPBKDFAlgorithm,
UnsafePointer,size_t,UnsafePointer,
CcpseudoRandomAlgorithm,uint,UnsafeMutablePointer,size_t)’

我相信所有演员阵容都是正确的(实际上编译器错误帮助我识别每个参数的每个问题) – 这让我觉得编译器理解我调用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
有必要为项目建立一个桥接头:
#import< CommonCrypto / CommonCrypto.h>
将Security.framework添加到项目中.

参数:

password     password String  salt         salt Data  keyByteCount number of key bytes to generaterounds       Iteration roundsreturns      Derived keyfunc 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 = 16let rounds       = 100000let 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 = 300var 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))
总结

以上是内存溢出为你收集整理的Swift:如何从Swift调用CCKeyDerivationPBKDF全部内容,希望文章能够帮你解决Swift:如何从Swift调用CCKeyDerivationPBKDF所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1049496.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存