在IOS中实施PBEKeySpec加密

时间:2015-10-24 06:31:00

标签: objective-c hash pbkdf2

这是我的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中使用的算法是否有任何问题

1 个答案:

答案 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