AES Encryption for an NSString on the iPhone AES Encryption for an NSString on the iPhone objective-c objective-c

AES Encryption for an NSString on the iPhone


Since you haven't posted any code, it's difficult to know exactly which problems you're encountering. However, the blog post you link to does seem to work pretty decently... aside from the extra comma in each call to CCCrypt() which caused compile errors.

A later comment on that post includes this adapted code, which works for me, and seems a bit more straightforward. If you include their code for the NSData category, you can write something like this: (Note: The printf() calls are only for demonstrating the state of the data at various points — in a real application, it wouldn't make sense to print such values.)

int main (int argc, const char * argv[]) {    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    NSString *key = @"my password";    NSString *secret = @"text to encrypt";    NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding];    NSData *cipher = [plain AES256EncryptWithKey:key];    printf("%s\n", [[cipher description] UTF8String]);    plain = [cipher AES256DecryptWithKey:key];    printf("%s\n", [[plain description] UTF8String]);    printf("%s\n", [[[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding] UTF8String]);    [pool drain];    return 0;}

Given this code, and the fact that encrypted data will not always translate nicely into an NSString, it may be more convenient to write two methods that wrap the functionality you need, in forward and reverse...

- (NSData*) encryptString:(NSString*)plaintext withKey:(NSString*)key {    return [[plaintext dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptWithKey:key];}- (NSString*) decryptData:(NSData*)ciphertext withKey:(NSString*)key {    return [[[NSString alloc] initWithData:[ciphertext AES256DecryptWithKey:key]                                  encoding:NSUTF8StringEncoding] autorelease];}

This definitely works on Snow Leopard, and @Boz reports that CommonCrypto is part of the Core OS on the iPhone. Both 10.4 and 10.5 have /usr/include/CommonCrypto, although 10.5 has a man page for CCCryptor.3cc and 10.4 doesn't, so YMMV.


EDIT: See this follow-up question on using Base64 encoding for representing encrypted data bytes as a string (if desired) using safe, lossless conversions.


I have put together a collection of categories for NSData and NSString which uses solutions found on Jeff LaMarche's blog and some hints by Quinn Taylor here on Stack Overflow.

It uses categories to extend NSData to provide AES256 encryption and also offers an extension of NSString to BASE64-encode encrypted data safely to strings.

Here's an example to show the usage for encrypting strings:

NSString *plainString = @"This string will be encrypted";NSString *key = @"YourEncryptionKey"; // should be provided by a userNSLog( @"Original String: %@", plainString );NSString *encryptedString = [plainString AES256EncryptWithKey:key];NSLog( @"Encrypted String: %@", encryptedString );NSLog( @"Decrypted String: %@", [encryptedString AES256DecryptWithKey:key] );

Get the full source code here:

https://gist.github.com/838614

Thanks for all the helpful hints!

-- Michael


@owlstead, regarding your request for "a cryptographically secure variant of one of the given answers," please see RNCryptor. It was designed to do exactly what you're requesting (and was built in response to the problems with the code listed here).

RNCryptor uses PBKDF2 with salt, provides a random IV, and attaches HMAC (also generated from PBKDF2 with its own salt. It support synchronous and asynchronous operation.