Encrypting and Decrypting NSData with AES256

Today we’re gonna encrypt information, stored in a NSData object, using AES-256 algorithm. As you may already know, AES-256 is a symmetric encryption schema. Which means that you need to share, somehow, the key you’re gonna use (in order to decrypt the data).

I’ve encapsulated a couple helper methods, as a NSData extension, for the sake of simplicity. I’ve based myself on this. Let’s see…

- (NSData*)aes256EncryptWithKey:(NSString*)key
{
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256 + 1];
    bzero( keyPtr, sizeof( keyPtr ) );

    // fetch key data
    [key getCString:keyPtr maxLength:sizeof( keyPtr ) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [self length];

    // See the doc: For block ciphers, the output size will always be less than or equal to the input size plus the size of one block.
    // That's why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc( bufferSize );

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted );
    if( cryptStatus == kCCSuccess )
    {
        // The returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }

    free( buffer );
    return nil;
}

And now… the decrypt routine…

- (NSData*)aes256DecryptWithKey:(NSString*)key
{
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256+1];
    bzero( keyPtr, sizeof( keyPtr ) );

    // fetch key data
    [key getCString:keyPtr maxLength:sizeof( keyPtr ) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [self length];

    // See the doc: For block ciphers, the output size will always be less than or equal to the input size plus the size of one block.
    // That's why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc( bufferSize );

    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt( kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesDecrypted );

    if( cryptStatus == kCCSuccess )
    {
        // The returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }

    free( buffer );
    return nil;
}

Ahhhh… don’t you forget about the imports!

#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>

Encode your email in base64, and confuse spammers!

How many of you run a website? come on! raise your hands!. Most of you should know, at this point, that publishing your email (in raw) is a pretty bad idea. Spammers, scammers, and whatsoever will target you, almost for sure.

So what can you do?. Well.. you can try encoding your email in base64!. Which means that… the browser will understand your email, it’ll get printed… but any automated spider-bot will fail to search ‘@gmail’… at least without consuming quite a lot of CPU power.

So… if you’re still interested, try this link. I’ve found it really helpful!.

Fixing ñ characters in code-igniter

It seems this is one of the oldest issues of PHP develoment, right?. I’ve developed a PHP website, based on codeigniter framework (and a mysql database), and i ran into a lot of problems with the ñ, not showing up well in google.

Here’s what i’ve done to fix this problem:

  1. Set the database collation / columns to utf8_general_ci (by means of phpmyadmin).
  2. In codeigniter’s ‘config.php’ file.
    $config['charset'] = 'UTF-8';
  3. In codeigniter’s ‘database.php’:
    $db['default']['char_set'] = 'utf8';
    $db['default']['dbcollat'] = 'utf8_general_ci';
  4. In the ‘general’ html-rendering, before anything else gets echo’ed (beware, i’m using HTML5.. HTML4 is different):
    <meta charset="UTF-8">
  5. And finally… in my .htaccess file:
    AddDefaultCharset UTF-8

I hope this helps. I’ve spent many hours reading… testing… and a couple days waiting for Google’s update!.

Fixing ‘SAFE MODE Restriction in effect. The script whose uid is is not allowed to access /tmp’ error in WordPress

Long short story. If you wanna update, say, a plugin, or a theme.. using wordpress, and you get the following error:

SAFE MODE Restriction in effect. The script whose uid is  is not allowed to access /tmp

I’ve got news for you!. It’s caused by the php_safe_mode flag. If you’re on a shared hosting, and you cannot change that flag (or maybe you just don’t want to)… here’s what you need to do:

  1. Create a temporary folder, somewhere in your hosting, and set the permissions to 777.
  2. Open your wp-config.php file.
  3. Add this line: define(‘WP_TEMP_DIR’,’/absolute/path/to-a-tmp-folder/’);

That should do the trick.

Fixing WebKitLocalStorageDatabasePathPreferenceKey crash

I’ve been getting a lot of crashes with the following signature:

Exception Type:  SIGABRT
Exception Codes: #0 at 0x351be32c
Crashed Thread:  0

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: WebKitLocalStorageDatabasePathPreferenceKey)'

What is this?. It’s pretty well explained here.
My workaround?. Quite simple. Call this method as soon as your app launches:

-(void)fixWebkitCrash
{
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    NSString* webkitPath = [defaults objectForKey:@"WebKitLocalStorageDatabasePathPreferenceKey"];
    NSString* bundlePath = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
   
    if([webkitPath containsString:bundlePath] == NO)
    {
        [defaults removeObjectForKey:@"WebKitLocalStorageDatabasePathPreferenceKey"];
        [defaults synchronize];
    }
}

Hopefully, this will save you a couple hours!.