Monday, November 25, 2013

Keep it secret!

With the latest release, AeroGear iOS 1.3.0 comes with more enhanced security features. Latest adding is encryption. In this release we deal with symmetric encryption.

Symmetric encryption: what is it?


Sometime talking about security topics might seem a bit overwhelming. But no worries, let's get the right vocabulary. When talking about encryption, there are actually two basic techniques for encrypting information: symmetric encryption (also called secret key encryption) and asymmetric encryption (also called public key encryption).

Today, we're going to delve into symmetric encryption as asymmetric one will be included in next AeroGear release. As said, symmetric encryption is when the same key is used to encrypt and decrypt data. Again, let's get the right jargon. Private key encryption is best defined with the following concepts:
  • Encryption key is a block of bytes of a _specific length_. Key can be derived from password using for example, PBKDF2 algorithm. Key must be kept secret.
  • IV (Initialisation Vector) is a random value that is used to encrypt data. Encryption algorithms usually work on fixed-size blocks, IV defines the first encrypted block.
You can derive the encryption key using a password or phassphrase and salt with AGPBKDF2.
  • Password is easy to remember and usually defined by user and must be kept secret. A password is not a key.
  • Salt is a random value that is used together with a password to derive an encryption key. A salt value does not need to be kept secret.
AeroGear-Crypto symmetric encryption provides you an easy way to encrypt your sensitive data. No need to be a security expert to use the library. See by yourself.

An example please: Xmas


Christmas is coming, it's all around us. Papillotes (french Christmas chocolate) and clementine is in the air. Surrounded by nephews and friends, it's time to organize your Santa Claus list. But you don't want your secret list to leak. Here comes into the scene your aerogear-crypto libraries.

In Xmas, we want to achieve local encryption of the present description but keep information like to whom the present is for, clear and searchable. The flow is simple you add a present to the list with an associated password and you saved it. It is first encrypted and then locally saved.

The list of present is displayed with a generic picture. If you want to remember what the item is. just click on it entered the password used for encryption, and the card will be flipped to show you the content description in clear.



Show me the code


Derive Key


First of all, to encrypt your data you need an encryption key. Your key can be derived from your password using PBKDF2 algorithms.
 -(NSData*) getKeyFromPassword:(NSString*)password {
     AGPBKDF2* derivator = [[AGPBKDF2 alloc] init];
     
     return [derivator deriveKey:password salt:_salt];
 }
To derive you key from your password you need to introduce some randomness (remember we talked about salt). For random generation of salt or IV, use AGRandomGenerator. By default, AGRandomGenerator generates 16 bytes key, but you can also specify the length if you wish.
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    _salt = [defaults objectForKey:@"xmas.salt"];
    
    if(!_salt) { // if first launch, initialize params for subsequent reads
        _salt = [AGRandomGenerator randomBytes];
        [defaults setObject:_salt forKey:@"xmas.salt"];
        [defaults synchronize];
    }

You need to store your salt to be able to regenerate the exact same key when you want to decrypt this description information. In this example, we've chosen to store this information in NSUserDefaults.

Encrypt


Once you've got your encryption key, use AGCryptoBox to do the actual encryption. With AGCryptoBox, you can encrypt/decrypt data using your encryption key and a randomly generated IV as shown below:
 -(void) saveAndEncryptData:(id)gift withPassword:password {
     // Generate key from password
     NSData* key = [self getKeyFromPassword:password];
     
     // Use CryptoBox to encrypt/decrypt data
     AGCryptoBox* cryptoBox = [[AGCryptoBox alloc] initWithKey:key];
     
     // transform string to data
     NSData* dataToEncrypt = [gift[@"description"] dataUsingEncoding:NSUTF8StringEncoding];
     
     // encrypt data
     gift[@"description"] = [cryptoBox encrypt:dataToEncrypt IV:_IV];
     
     // Store data with encrypted description
     [_store save:gift error:nil];
     
     [self.gifts addObject:gift];
 }
Same as for the salt, IV need to be store to be able to decrypt the encrypted data. We'll put it into NSUserDefaults too.

Decrypt


To be able to decrypt, fetch salt, prompt the user for password, regenerate the encryption key. Fetch IV data and decrypt!
 -(NSString*)decrypt:(NSData*)data {
     NSData* key = [self getKeyFromPassword:_password];
     AGCryptoBox* cryptoBox = [[AGCryptoBox alloc] initWithKey:key];

     return [[NSString alloc]
             initWithData:[cryptoBox decrypt:data IV:_IV] encoding:NSUTF8StringEncoding];
 }

That's all folks!
If you want to see it all in action, git clone cookbook, go to xmas app and pod install it :)

1 comment:

  1. Thank you so much for simplifying all about this mechanism. I was curious to learn about this process but the information I collected so far was really difficult to understand. I like the detail you have shared.
    digital signatures

    ReplyDelete

Note: Only a member of this blog may post a comment.