Securely storing OAuth keys in iOS application
Post date: Jun 28, 2013 6:33:31 AM
Recently I was involved in iOS native application which is accessing Restful OAuth web service. Client provided OAuth API key and Secrete Key to access their web service.
So we just put on "Plist" and we start using this for web service call. Once we done a application we start digging the security flaws in our application. We realise that "PLIST" values will be available to everyone once you extract the .IPA file.
So we decide to AES encryption to Encrypt the API and Secrete keys then stored it plist.
Again we found below drawback:
AES key will be hardcoded in one of the ObjectiveC implementation file (.m).
Any hardcoded strings will be available somewhere in the .iPA file for iOS reference.
Security team again raised concern about the key which is showing in .iPA as it is.
At this point I don't have any idea about to hiding this key. So I decided to workaround.
Encrypt Plist:
I decide to encrypt my plist using AES algorithm. Here my AES key is "GreateIndiaClub@123"
The code I used for Encryption is:
-(NSString*)getEncryptedPlistInfo:(NSString*)resourceName{
//get the plist path
NSString * strPath= [[NSBundle mainBundle] pathForResource:resourceName ofType:@"plist"];
//convert it into dictionary
NSDictionary* dictionary= [[NSDictionary alloc]initWithContentsOfFile:strPath];
//conver into NSData
NSData *xmlData = [NSPropertyListSerialization dataFromPropertyList:dictionary
format:NSPropertyListXMLFormat_v1_0 errorDescription:nil];
//Apply AES encrytpion
NSData* encryptData = [ xmlData EncryptAES:@"GreateIndiaClub@123"];
//Encode with Base 64
NSString* strBase64= [QSStrings encodeBase64WithData:encryptData];
//Return cipher text
return strBase64;
}
Don't forget to Delete this function from your project once you done a encryption.
After encryption I got the cipher text mentioned below:
BxcLIWJ720ZztUO1uRwIOEATvjbRyeh8ny6G0Nq2sS/uaB6QD584ASjkpddHnlc+LsPDXeBJPau16fh1
GVAsB09J8Cl6KrnzakHssHyYWsVfV4lYPMSUhzGnd0szPu+JyNud3H91yr+x65fSTywc45eDhS7r
SG2wd8byPvYdbHh/mWW4k2Az+m6IZw7WDq9n46roDp53FPn2CkcV5XXbh3BJEtQVBzVm9/
CRYmdFdNS4i9UKX1ND0WWpeBRuHP3qtJQUBoCuX7c8dN0smhx51wLcHxgY4+cPE+sjWGb
6slNWi5HejF7PC1fjawJyJmfE9mlQoyF3hxATJGyxQJinNCZ6FfSZ0cDcjv3lQQZZZRN6e0UTQ
TSipS729a4trD2hVgmJk7NBNAup26FkFGlGKA==
Modify the cipher text:
Now we need append AES key with this cipher text, so that it will became as invalid cipher text. So no can able to use this. The new cipher text will be
GreateIndiaClub@123BxcLIWJ720ZztUO1uRwIOEATvjbRyeh8ny6G0Nq2sS/uaB6QD5
84ASjkpddHnlc+L
sPDXeBJPau16fh1GVAsB09J8Cl6KrnzakHssHyYWsVfV4lYPMSUhzGnd
0szPu+JyNud3H91yr+x65fSTywc45eDhS7rSG2wd8byPvYdbHh/mWW4k2Az
+m6IZw7WDq9n46roDp53FPn2CkcV5XXbh3BJEtQVBzVm9/CRYm
dFdNS4i9UKX1ND0WWpeBRuHP3qtJQUBoCuX7c8dN0smhx51wLcHxgY4+cPE+sj
WGb6slNWi5H ejF7PC1fjawJyJmfE9mlQoyF3hxATJGyxQJinNCZ6FfSZ0cDcjv3lQQZ
ZZRN6e0UTQTSipS729a4trD2hV
gmJk7NBNAup26FkFGlG KA==
Makes key more complex by applying your own algorithm:
To make your secrete key more complex append some text with your key with some logic
Original Key : GreateIndiaClub@123
Modified Key : GOr3ePa=tAe8IRnDd9i/aUCFlau3bi@h1k2l3
So here the logic is EVEN position contains the original key, just have to omit the ODD position of the characters
Now add this key in your plist cipher text:
GOr3ePa=tAe8IRnDd9i/aUCFlau3bi@h1k2l3BxcLIWJ720ZztUO1uRwIOEATv
jbRyeh8ny6G0Nq2sS/uaB6QD584ASjkpddHnlc+LsPDXeBJPau16fh
1GVAsB09J8Cl6KrnzakHss HyYWsVfV4lYPMSUhzGnd0szPu+JyNud3H91yr+x65fST
ywc45eDhS7rSG2wd8byPvYdbHh/mWW4k2Az+m6IZw7WDq9n46roDp53FP n2Ckc
V5XXbh3BJEtQVBzVm9/CRYmdFdNS4i9
UKX1ND0WWpeBRuHP3qtJQUBoCuX7c8dN0s
mhx51wLcHxgY4+cPE+sjWGb6slNWi5HejF7PC1fjawJyJmfE9mlQoyF3hx
ATJGyxQJinNCZ6FfSZ0cDcjv3lQQZZZRN6e0UTQTSipS729a
4trD2hVgmJk7NBNAup26FkFGlG KA==
Now add this key in your plist and delete the earlier plist:
New PLIST
All these should be done manually before the application deployment. You should Delete getEncryptedPlistInfo once encrypt the plist.
Now new plist has encrypted plist with modified AES Key.
Decrypt PLIST:
1. Get value from PLIST
2. Separate the Modified AES Key and Encrypted key. You should know the modified AES key length, In our case it was 37 character length
3. Parse the AES Key with your algorithm, here we had original key at EVEN postion
4. Apply AES decryption using parsed AES key, you will get the Decrypted Plist dictionary as output.
Function used to Decrypt the PLIST:
-(NSDictionary*)getConfigurationPlist{
//get the plist path
NSString * strPath= [[NSBundle mainBundle] pathForResource:@"Test" ofType:@"plist"];
//convert it into dictionary
NSDictionary* dictStoreScanner= [[NSDictionary alloc]initWithContentsOfFile:strPath];
//Read the new Plist, which has encrypted value with Modified AES key
NSString* strPlist =[dictStoreScanner valueForKey:@"Info"];
//Get Modified AES Key
if ([strPlist length]>37) {
NSString* strKey= [strPlist substringToIndex:37];
NSMutableString* strAES=[NSMutableString string];
//Parse the Modifed values and get the originial key, You should apply your own algorithm here
for (int i=0; i<strKey.length; i++) {
//Here I'm looking for EVEN position of the characters only
if (i%2==0) {
[strAES appendFormat:@"%c", [strKey characterAtIndex:i]];
}
}
//get the encrypted text for plist
NSString* strEncryptedPlist = [strPlist substringWithRange:NSMakeRange(37,
[strPlist length]-37)];
//decrypt the text
NSData* plistData=[QSStrings decodeBase64WithString:strEncryptedPlist];
plistData = [ plistData DecryptAES:strAES andForData: nil];
NSPropertyListFormat plistFormat;
//parse the data and get the dictionary (NSData - NSDictionary)
NSDictionary* dictValue =[NSPropertyListSerialization
propertyListWithData:plistData options:NSPropertyListImmutable
format:&plistFormat error:nil];
return dictValue;
}
return nil;
}
By calling above function you will get APIkey and Secretekey from the dictionary;
Printing description of dictValue:
{
APIKey = "ApiKey@123";
SecreteKey = "SecreteKey@123";
}
Advantages:
Hacking is so difficult since hacker don't have a proper cipher text in plist
To hack this code they should know to separate Modified AES key from Cipher text.
Thou they found Modified AES key, they don't have any clue about the appending algorithm, here i simple used EVEN position of the character, but you can't modify this and you can take 3rd or 4th position of the character. Which is actually will differ for each developer
Hope you enjoy this concept. Please let me know if you have any queries.