在 IOS 中实施 PBEKeySpec 加密
implementing PBEKeySpec encryption into IOS
这是我的 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
中使用的算法有问题吗
使用 Common Crypto CCKeyDerivationPBKDF
函数和选项 kCCPRFHmacAlgSHA1
。
注意PBEKeySpec
keyLength
以位为单位,CCKeyDerivationPBKDF
derivedKeyLen
以字节为单位。
要获得更详细的答案,请提供所有输入(hashKey、salt)和十六进制转储格式的输出加上轮数、以字节为单位的输出长度。
查看示例代码SO answer。
Update for revised question code:
CCKeyDerivationPBKDF
returns 8 位数据字节,本质上不是字符,即使强制进入 NSASCIIStringEncoding
,许多字节也不可打印。即使没有返回错误也强制 NSASCIIStringEncoding
是不正确且无用的。而是使用返回的 NSData
或转换为 Base64 或 HexASCII 编码。
改变
NSString *myString = [[NSString alloc] initWithData:derivedKey encoding:NSASCIIStringEncoding];
Output: A´Öº÷"ùïó
至
NSString * myString = [derivedKey base64EncodedStringWithOptions:0];
Output: QbTWgbr3FSL57/MfBQAz4A==
注意:1000 发通常被认为不够用,应该使用 10,000 到 100,000 范围内的东西。
iPhone 6S 的计时:
rounds seconds
1000 0.003
10000 0.032
100000 0.309
1000000 3.047
这是我的 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
中使用的算法有问题吗使用 Common Crypto CCKeyDerivationPBKDF
函数和选项 kCCPRFHmacAlgSHA1
。
注意PBEKeySpec
keyLength
以位为单位,CCKeyDerivationPBKDF
derivedKeyLen
以字节为单位。
要获得更详细的答案,请提供所有输入(hashKey、salt)和十六进制转储格式的输出加上轮数、以字节为单位的输出长度。
查看示例代码SO answer。
Update for revised question code:
CCKeyDerivationPBKDF
returns 8 位数据字节,本质上不是字符,即使强制进入 NSASCIIStringEncoding
,许多字节也不可打印。即使没有返回错误也强制 NSASCIIStringEncoding
是不正确且无用的。而是使用返回的 NSData
或转换为 Base64 或 HexASCII 编码。
改变
NSString *myString = [[NSString alloc] initWithData:derivedKey encoding:NSASCIIStringEncoding];
Output: A´Öº÷"ùïó
至
NSString * myString = [derivedKey base64EncodedStringWithOptions:0];
Output: QbTWgbr3FSL57/MfBQAz4A==
注意:1000 发通常被认为不够用,应该使用 10,000 到 100,000 范围内的东西。
iPhone 6S 的计时:
rounds seconds 1000 0.003 10000 0.032 100000 0.309 1000000 3.047