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.
- 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.
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 :)
Tweet
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.
ReplyDeletedigital signatures