这是我的java代码。现在我想在Objective-C中实现相同的功能。
int dkLen = 16;
int rounds = 1000;
PBEKeySpec keySpec = new PBEKeySpec(hashKey.toCharArray(),salt.getBytes(), rounds, dkLen * 8);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
return factory.generateSecret(keySpec).getEncoded();
这是我的iOS实现
- (void)getHashKey {
NSString *hash_key=@"MY_HASHKEY";
NSString *saltKey = @"MY_SALTKEY";
int dkLen = 16;
NSData *keyData = [hash_key dataUsingEncoding:NSUTF8StringEncoding];
NSData *salt = [saltKey dataUsingEncoding:NSUTF8StringEncoding];
uint rounds = 1000;
uint keySize = kCCKeySizeAES128;
NSMutableData *derivedKey = [NSMutableData dataWithLength:keySize];
CCKeyDerivationPBKDF(kCCPBKDF2, // algorithm
keyData.bytes, // password
keyData.length, // passwordLength
salt.bytes, // salt
salt.length, // saltLen
kCCPRFHmacAlgSHA1, // PRF
rounds, // rounds
derivedKey.mutableBytes, // derivedKey
dkLen*8); // derivedKeyLen
NSString *myString = [[NSString alloc] initWithData:derivedKey encoding:NSASCIIStringEncoding];
NSLog(@"derivedKey: %@", myString);
}
我在iOS中使用的算法是否有任何问题
答案 0 :(得分:3)
将Common Crypto CCKeyDerivationPBKDF
函数与kCCPRFHmacAlgSHA1
选项一起使用。
注意PBEKeySpec
keyLength
为位,CCKeyDerivationPBKDF
derivedKeyLen
以字节为单位。
更详细的答案提供所有输入(hashKey,salt)和十六进制转储格式的输出加上轮数,输出长度(以字节为单位)。
有关示例代码,请参阅此SO answer。
修订后的问题代码更新:
CCKeyDerivationPBKDF
返回8位数据字节,这些字节本质上不是字符,即使强制进入NSASCIIStringEncoding
,许多字节也不可打印。即使没有返回错误,强制NSASCIIStringEncoding
也是错误的,没有用处。而是使用返回的NSData
或转换为Base64或HexASCII编码。
更改
NSString *myString = [[NSString alloc] initWithData:derivedKey encoding:NSASCIIStringEncoding];
输出:A'Öº÷“ùïó
到
NSString * myString = [derivedKey base64EncodedStringWithOptions:0];
输出:QbTWgbr3FSL57 / MfBQAz4A ==
注意:通常认为1000轮不足,应使用10,000到100,000范围内的轮次。
iPhone 6S上的计时:
rounds seconds 1000 0.003 10000 0.032 100000 0.309 1000000 3.047