I'm trying to use CommonCrypto
to generate keys using PBKDF2
but I can't seem to importCommonCrypto/CommonKeyDerivation.h
, I just errors that it is not found.
Any ideas?
edit: I should probably mention I have already added the security framework and I can import all of the other CommonCrypto
headers.
#import <CommonCrypto/CommonKeyDerivation.h> ... // Makes a random 256-bit salt - (NSData*)generateSalt256 { unsigned char salt[32]; for (int i=0; i<32; i++) { salt[i] = (unsigned char)arc4random(); } return [NSData dataWithBytes:salt length:32]; } ... // Make keys! NSString* myPass = @"MyPassword1234"; NSData* myPassData = [myPass dataUsingEncoding:NSUTF8StringEncoding]; NSData* salt = [self generateSalt256]; // How many rounds to use so that it takes 0.1s ? int rounds = CCCalibratePBKDF(kCCPBKDF2, myPassData.length, salt.length, kCCPRFHmacAlgSHA256, 32, 100); // Open CommonKeyDerivation.h for help unsigned char key[32]; CCKeyDerivationPBKDF(kCCPBKDF2, myPassData.bytes, myPassData.length, salt.bytes, salt.length, kCCPRFHmacAlgSHA256, rounds, key, 32);
another:
Are you building for iOS5 ? or earlier versions ?
Both API, CCKeyDerivationPBKDF
and CCCalibratePBKDF
, defined in the header file are only available on IOS5 (or OSX 10.7) and later.
You can make sure the file exists by executing this inside a terminal window:
$ find /Developer/ -name CommonKeyDerivation.h /Developer//Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/include/CommonCrypto/CommonKeyDerivation.h /Developer//Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/include/CommonCrypto/CommonKeyDerivation.h /Developer//SDKs/MacOSX10.7.sdk/usr/include/CommonCrypto/CommonKeyDerivation.h
another:
I had the similar problem. But I found a way on link: How to create PBKDF2 key on iOS device Posting answer from the above link:
You can use the PKCS5_PBKDF2_HMAC_SHA1() function in openssl/evp.h. Divining how to use the function is pretty easy from the declaration:
int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out);
Using above, I wrote the following code which worked for me:
#import <CommonCrypto/CommonCryptor.h> #import <openssl/evp.h> const CCAlgorithm kAlgorithm = kCCAlgorithmAES128; const NSUInteger kAlgorithmKeySize = kCCKeySizeAES128; const NSUInteger kAlgorithmBlockSize = kCCBlockSizeAES128; + (NSData *)AESKeyForPassword:(NSString *)password salt:(NSData *)salt { NSMutableData * derivedKey = [NSMutableData dataWithLength:kAlgorithmKeySize]; int result = PKCS5_PBKDF2_HMAC_SHA1(password.UTF8String, (int)[password length], salt.bytes, (int)[salt length], 10000, (int)[derivedKey length], derivedKey.mutableBytes); NSAssert(result == 1, @"Unable to create AES key for password: %d", result); return derivedKey; } + (NSData *)encryptedDataForData:(NSData *)data password:(NSString *)password iv:(NSData **)iv salt:(NSData **)salt error:(NSError **)error { NSData *key = [self AESKeyForPassword:password salt:*salt]; size_t outLength; NSMutableData * cipherData = [NSMutableData dataWithLength:data.length + kAlgorithmBlockSize]; CCCryptorStatus result = CCCrypt(kCCEncrypt, // operation kAlgorithm, // Algorithm kCCOptionPKCS7Padding, // options key.bytes, // key key.length, // keylength (*iv).bytes,// iv data.bytes, // dataIn data.length, // dataInLength, cipherData.mutableBytes, // dataOut cipherData.length, // dataOutAvailable &outLength); // dataOutMoved if (result == kCCSuccess) { cipherData.length = outLength; } else { if (error) { *error = [NSError errorWithDomain:@"error" code:result userInfo:nil]; } return nil; } return cipherData; } // =================== + (NSData *)decryptedDataForData:(NSData *)data password:(NSString *)password iv:(NSData **)iv salt:(NSData **)salt error:(NSError **)error { NSData *key = [self AESKeyForPassword:password salt:*salt]; size_t outLength; NSMutableData * cipherData = [NSMutableData dataWithLength:data.length + kAlgorithmBlockSize]; CCCryptorStatus result = CCCrypt(kCCDecrypt, kAlgorithm, kCCOptionPKCS7Padding, key.bytes, key.length, (*iv).bytes , data.bytes, data.length, cipherData.mutableBytes, cipherData.length, &outLength); if (result == kCCSuccess) { cipherData.length = outLength; } else { if (error) { *error = [NSError errorWithDomain:@"error" code:result userInfo:nil]; } return nil; } return cipherData; }
The question is directed at a CC implementation. Apple discourages the use of OpenSSL.
How to create PBKDF2 key on iOS device
I need to create a PBKDF2 key to use in my AES encryption routine in my iPhone Xcode application. I have seen references to using OpenSSL to do this, but not found specific references to what module within OpenSSL to call.
I have scanned various OpenSSL .h files searching for a means to make this call, but have so far been unsuccessful.
The key I will be using is 5-digits, Salt is 12 characters, Iterations is 1000, and I need a 128-bit generated key.
answer:
You can use the PKCS5_PBKDF2_HMAC_SHA1()
function in openssl/evp.h
. Divining how to use the function is pretty easy from the declaration:
int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out);
another:
I think p5_crpt2.c is what you are looking for.