Swift调用CryptoSwift实现PBKDF2密钥派生耗时过长求优化方案
性能问题根因
你当前使用的CryptoSwift是纯Swift实现的加密库,未调用苹果系统底层经过硬件加速、汇编优化的加密接口,所以高迭代次数下PBKDF2密钥派生的性能远低于其他平台的原生实现,就算是Release模式也和原生方案有量级差距。
最优解决方案:替换为苹果系统原生PBKDF2实现
苹果系统自带的CommonCrypto框架的PBKDF2接口经过高度优化,相同10000次迭代、AES256、SHA256参数下,密钥派生耗时通常在10ms以内,完全满足性能要求,且生成的密钥和你现有CryptoSwift实现的结果完全一致,不影响跨平台兼容性。
替换后的代码示例(支持iOS10+,兼容你现有参数)
首先需要在项目的Objective-C桥接头文件中引入CommonCrypto:
#import <CommonCrypto/CommonCrypto.h>
然后新增原生PBKDF2派生方法,替换原有CryptoSwift的密钥派生逻辑即可:
import Foundation func pbkdf2DeriveKey(password: String, salt: [UInt8], iterations: UInt32, keyLength: Int) -> [UInt8]? { guard let passwordData = password.data(using: .utf8) else { return nil } var derivedKey = [UInt8](repeating: 0, count: keyLength) let status = CCKeyDerivationPBKDF( CCPBKDFAlgorithm(kCCPBKDF2), password, passwordData.count, salt, salt.count, CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256), iterations, &derivedKey, derivedKey.count ) guard status == kCCSuccess else { return nil } return derivedKey }
原有解密函数中替换密钥生成部分的代码即可:
// 替换原来的PKCS5.PBKDF2.calculate()部分代码 guard let key = pbkdf2DeriveKey(password: masterPass, salt: salt, iterations: 10000, keyLength: 32) else { return "error in key derivation" }
额外优化建议
- 如果存在相同密码+相同盐多次派生密钥的场景,可以把派生后的密钥缓存到内存/钥匙串中,避免重复计算,进一步提升响应速度
- 如果你最低支持iOS13+,也可以搭配CryptoKit实现AES-GCM解密,性能会比CryptoSwift的AES实现更高。
内容的提问来源于stack exchange,提问作者metamonkey
相关产品推荐
相关产品推荐

