Reputation: 35
I think this generates random 64 bytes NSData.
uint8_t buffer[64];
SecRandomCopyBytes(kSecRandomDefault, 64, buffer);
NSData *keyData = [[NSData alloc] initWithBytes:buffer length:sizeof(buffer)];
I want to generate 64 bytes NSData like this but not a random data. How can I generate 64 bytes NSData with a given key like "com.this.is.akey".
Tried this one but it gave me wrong bytes size(not 64 bytes).
NSString *base64EncodedString = [[@"somekey.here" dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
NSData *encodedData = [[NSData alloc] initWithBase64EncodedString:base64EncodedString
options:0];
Upvotes: 2
Views: 2363
Reputation: 112857
Given a string for a key one should use a key derivation function such as PBKDF2.
Example:
#import <CommonCrypto/CommonCrypto.h>
NSString *keyString = @"com.this.is.key"; // Should use a random value
NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
NSData *salt = [@"saltstring" dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *derivedKey = [NSMutableData dataWithLength:CC_SHA512_DIGEST_LENGTH];
CCKeyDerivationPBKDF(kCCPBKDF2,
keyData.bytes, keyData.length,
salt.bytes, salt.length,
kCCPRFHmacAlgSHA512,
10000, // Choose for desired timing
derivedKey.mutableBytes, derivedKey.length);
NSLog(@"derivedKey: %@", derivedKey);
Output: derivedKey:
065d2106 1da7ebcf d155a50a b1ee5540 dee8efce f4678c47 02164488 e92e05e5 30c1f12d a3813013 652aca1b 0016b258 610d7929 f240de72 3eab85d9 7e028b35
Notes:
It is best to set the salt to a random value and provide it along with the derived key.
The iteration count should set to provide a suitable derivation tine, perhaps 100ms. There is a corresponding CCCalibratePBKDF
function the help with this. The iteration count can also be provided along with the derived key.
Sorry if this seems to be more work that necessary but security is not easy to get right.
Upvotes: 1
Reputation: 10573
You can use -[NSString dataUsingEncoding:]
to convert NSString
to NSData
.
NSString *key = @"com.this.is.akey";
NSData *keyData = [key dataUsingEncoding:NSASCIIStringEncoding];
If length of the data is less or greater than 64 bytes, you should pad or truncate data to exact 64 bytes.
if (keyData.length != 64) {
NSMutableData *mutableData = keyData.mutableCopy;
mutableData.length = 64;
keyData = mutableData.copy;
}
Then, you can pass the NSData
object to RLMRealmConfiguration.encryptionKey
.
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.encryptionKey = keyData;
NSError *error = nil;
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error];
Upvotes: 2