Apple Keychain Services offer a secure means to store sensitive information. Through the keychain, all the hardwork is managed for you to store and retrieve content. As powerful as the keychain services are, I was recently tinkering with some code to see if I could obfuscate content within an application.
I had a few strings defined as constants and I was interested to see if there was a painless way to store the values as obfuscated strings, and when running the application, un-obfuscate the strings and use the same within the application.
Using Exclusive-Or (XOR) to Obfuscate an NSString
The basic concept is that for each character in a string, I XOR the value against a key value, replacing the original character with the new XOR’d character. This will create a string that is unrecognizable from the original. To get the original string back, perform the same XOR operation with the same key. The obfuscate method is shown below.
- (NSString *)obfuscate:(NSString *)string withKey:(NSString *)key
{
// Create data object from the string
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
// Get pointer to data to obfuscate
char *dataPtr = (char *) [data bytes];
// Get pointer to key data
char *keyData = (char *) [[key dataUsingEncoding:NSUTF8StringEncoding] bytes];
// Points to each char in sequence in the key
char *keyPtr = keyData;
int keyIndex = 0;
// For each character in data, xor with current value in key
for (int x = 0; x < [data length]; x++)
{
// Replace current character in data with
// current character xor'd with current key value.
// Bump each pointer to the next character
*dataPtr = *dataPtr++ ^ *keyPtr++;
// If at end of key data, reset count and
// set key pointer back to start of key value
if (++keyIndex == [key length])
keyIndex = 0, keyPtr = keyData;
}
return [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
}
Test Obfuscation
Pass in the string to obfuscate as well as a key which will provide the characters to use in the XOR process. To un-obfuscate a string, call the method with the obfuscated string and the same key.
Below is a short test of the obfuscation:
NSString *str = @"iPhoneDeveloperTips";
NSLog(@"Input string:%@", str);
// Obfuscate string
NSString *obfuscatedStr = [self obfuscate:str withKey:@"+@$"];
NSLog(@"Obfuscated string:%@", obfuscatedStr);
// Run obfuscate again to get the original string
str = [self obfuscate:obfuscatedStr withKey:@"+@$"];
NSLog(@"Final string:%@", str);
The output will look as follows:
Note: The resulting obfuscated string may include non-printable characters, so if you print to the console as shown above, don’t be surprised if the output contains what looks to be spaces or newline characters.
Caveat
For any number of reasons, including the key is stored as part of the application, this approach is by no means a substitution for real encryption. If you have sensitive data you need to protect, use the Keychain services. With that said, there are times when storing a string in a format other than clear text in your application may be of interest.
http://iphonedevelopertips.com/