How to avoid hardcoding keys for encryption (Objective C)? - ios

In my Objective C code, I have a consumer key and secret hardcoded in my code to be used in SHA-1 encryption. What I would like to know is whether I could avoid hardcoding to improve security. I have found the following so far,
Finding 1
https://www.owasp.org/index.php/Technical_Risks_of_Reverse_Engineering_and_Unauthorized_Code_Modification#Cryptographic_Key_Replacement
Steps explained are as follows,
Damage static keys that are declared in source code. Such keys should be damaged while on disk to prevent an adversary from analyzing and intercepting the original key;
Next, the application should repair the key just before the code requiring the key uses it;
Immediately before use of the key, the application should perform a checksum of the key’s value to verify that the non-damaged key matches the value that the code declares at build time; and
Finally, the application should immediately re-damage the key in memory after the application has finished using it for that particular call.
Finding 2
https://github.com/UrbanApps/UAObfuscatedString
Can somebody help me please?
Sample code:
+ (NSString *) getOauthHeaderForRequestString:(NSString *)requestString {
NSString *oauthConsumerKey = #"<consumer key which I want avoid hardcoding>";
NSString *oauthConsumerSecret = #"<consumer secret which I want to avoid hardcoding>";
NSString *oauthSignatureMethod = #"HMAC-SHA1";
NSString *oauthVersion = #"1.0";
NSString *oauthNonce = [self generateNonce];
NSString *oauthtimestamp = [NSString stringWithFormat:#"%d", (int)[[NSDate date] timeIntervalSince1970]];
NSArray * params = [NSArray arrayWithObjects:
[NSString stringWithFormat:#"%#%%3D%#", #"oauth_consumer_key", oauthConsumerKey],
[NSString stringWithFormat:#"%#%%3D%#", #"oauth_nonce", oauthNonce],
[NSString stringWithFormat:#"%#%%3D%#", #"oauth_signature_method", oauthSignatureMethod],
[NSString stringWithFormat:#"%#%%3D%#", #"oauth_timestamp", oauthtimestamp],
[NSString stringWithFormat:#"%#%%3D%#", #"oauth_version", oauthVersion],
[NSString stringWithFormat:#"%#%%3D%#", #"request", [requestString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]],
nil];
params = [params sortedArrayUsingSelector:#selector(compare:)];
NSString *parameters = [params componentsJoinedByString:#"%26"];
NSString *postURL = #"<my post url>";
NSArray * baseComponents = [NSArray arrayWithObjects:
#"POST",
[self encodeString:postURL],
parameters,
nil];
NSString * baseString = [baseComponents componentsJoinedByString:#"&"];
NSArray *signingKeyComponents = [NSArray arrayWithObjects:oauthConsumerSecret, #"", nil];
NSString *signingKey = [signingKeyComponents componentsJoinedByString:#"&"];
NSData *signingKeyData = [signingKey dataUsingEncoding:NSUTF8StringEncoding];
NSData *baseData = [baseString dataUsingEncoding:NSUTF8StringEncoding];
uint8_t digest[20] = {0};
CCHmac(kCCHmacAlgSHA1, signingKeyData.bytes, signingKeyData.length, baseData.bytes, baseData.length, digest);
NSData *signatureData = [NSData dataWithBytes:digest length:20];
NSString *oauthSignature = [self base64forData:signatureData];
// final request build
NSString *oauthHeader = #"OAuth ";
oauthHeader = [oauthHeader stringByAppendingFormat:#"oauth_consumer_key=\"%#\"",oauthConsumerKey];
oauthHeader = [oauthHeader stringByAppendingFormat:#",oauth_nonce=\"%#\"",oauthNonce];
oauthHeader = [oauthHeader stringByAppendingFormat:#",oauth_signature=\"%#\"",[self encodeString:oauthSignature]];
oauthHeader = [oauthHeader stringByAppendingFormat:#",oauth_signature_method=\"%#\"",oauthSignatureMethod];
oauthHeader = [oauthHeader stringByAppendingFormat:#",oauth_timestamp=\"%#\"",oauthtimestamp];
oauthHeader = [oauthHeader stringByAppendingFormat:#",oauth_version=\"1.0\""];
return oauthHeader;
}

I've written about the challenges of solving this problem before, but I wanted to demonstrate a little bit using your UAObfuscatedString idea, since I think this is the kind of solution most people are looking for, but is worse than nothing. It's important to note: I'm not particularly good at this. I'm not a seasoned reverse engineer and commercial systems are way beyond my skillset. I'm just a guy with Hopper and literally five minutes of reverse engineering work (I ran a timer; 5:35s, including upgrading Hopper because I hadn't run it in a few months).
So, I wrote an iOS program with UAObfuscatedString. I used Swift because Swift is generally a little harder to reverse engineer than ObjC. ObjC is a reverse engineer's dream.
let identifier = "c".o.m.dot.u.r.b.a.n.a.p.p.s.dot.e.x.a.m.p.l.e
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
print(identifier)
return true
}
I then archived it, so it's optimized code, etc. etc. just like you'd send to the App Store. I then loaded it up in to Hopper and looked at the app delegate's init. That's where constants are initialized, based on the assumption that most people stick this stuff in their app delegate. Obviously if I see a class named KeyStorage or SecretStuffHelper, I'd look there first....
void * -[_TtC13ObfuscateTest11AppDelegate init](void * self, void * _cmd) {
*(r31 + 0xffffffffffffffe0) = r20;
*(0xfffffffffffffff0 + r31) = r19;
*(r31 + 0xfffffffffffffff0) = r29;
*(r31 + 0x0) = r30;
r0 = sub_100005e14();
return r0;
}
Hmm, it calls this anonymous function sub_100005e14(). Let's see what that does.
...
0000000100005e38 adr x0, #0x100006859 ; "c"
...
0000000100005e48 bl imp___stubs___T0SS18UAObfuscatedStringE1oSSfg
...
0000000100005e50 bl imp___stubs___T0SS18UAObfuscatedStringE1mSSfg
...
0000000100005e74 bl imp___stubs___T0SS18UAObfuscatedStringE3dotSSfg
...
0000000100005e98 bl imp___stubs___T0SS18UAObfuscatedStringE1uSSfg
...
0000000100005ebc bl imp___stubs___T0SS18UAObfuscatedStringE1rSSfg
...
0000000100005ee0 bl imp___stubs___T0SS18UAObfuscatedStringE1bSSfg
...
0000000100005f04 bl imp___stubs___T0SS18UAObfuscatedStringE1aSSfg
...
0000000100005f28 bl imp___stubs___T0SS18UAObfuscatedStringE1nSSfg
...
0000000100005f4c bl imp___stubs___T0SS18UAObfuscatedStringE1aSSfg
...
0000000100005f70 bl imp___stubs___T0SS18UAObfuscatedStringE1pSSfg
...
0000000100005f94 bl imp___stubs___T0SS18UAObfuscatedStringE1pSSfg
...
0000000100005fb8 bl imp___stubs___T0SS18UAObfuscatedStringE1sSSfg
...
0000000100005fdc bl imp___stubs___T0SS18UAObfuscatedStringE3dotSSfg
...
0000000100006000 bl imp___stubs___T0SS18UAObfuscatedStringE1eSSfg
...
0000000100006024 bl imp___stubs___T0SS18UAObfuscatedStringE1xSSfg
...
0000000100006048 bl imp___stubs___T0SS18UAObfuscatedStringE1aSSfg
...
000000010000606c bl imp___stubs___T0SS18UAObfuscatedStringE1mSSfg
...
0000000100006090 bl imp___stubs___T0SS18UAObfuscatedStringE1pSSfg
...
00000001000060b4 bl imp___stubs___T0SS18UAObfuscatedStringE1lSSfg
...
00000001000060d8 bl imp___stubs___T0SS18UAObfuscatedStringE1eSSfg
I'm not sure why the Swift demangler isn't working here, but anyway, we can easily see the pattern:
_T0SS18UAObfuscatedStringE1oSSfg => o
_T0SS18UAObfuscatedStringE1mSSfg => m
_T0SS18UAObfuscatedStringE3dotSSfg => dot => .
_T0SS18UAObfuscatedStringE1uSSfg => u
...
Realizing there are these USObfuscatedString methods, I search for that and find everywhere in the app that uses obfuscated strings. If I was willing to up my game a little and spend a day or so playing with it, I could probably write a tool to automatically extract every UAObfuscatedString just using otool and the binary.
And this is the deep lesson. You've just labeled all the strings you want to hide. Once I realize that UAObfuscatedString is a thing, you just made it easier for me to find your sensitive information. It is literally worse than nothing. Your only hope here is that the attacker doesn't know this exists. That's the problem with obfuscation, and what separates obfuscation from security.
I want also to emphasize that I spent 5 minutes and 35 seconds attacking this program. Yes, I knew basically what kind of thing I was looking for, but I also have no skills at this. If UAObfuscatedString were to become popular, I assure you that the auto-detect/de-obfuscate tool would become part of every script-kiddie's toolbox ("script-kiddie" is what security folks call attackers who do not know what they're doing, and just use automated tools that others have written).
The lesson here is that if you want to obfuscate, you're better off making up some random approach yourself. It won't be effective, but it probably won't be actively harmful to your goal in the way that most FOSS solutions are. "Free and open source" can be very good for security, but are the worst possible thing for obscurity.
If hiding information is really important to your business plan and you can't change your business plan, then you should expect to spend a lot of money on this problem and hire a team of people dedicated to constantly evolving your obfuscation system to keep ahead of attackers who will adapt to whatever you build.

So I recommend use yours second finding
https://github.com/UrbanApps/UAObfuscatedString
and add the regenerated strings to the keychain at the first application launch
so all methods could use values from keychain later in you code.
also I recommend build a singleton that will provide access to such values too keep all in one for time you want to change or update this solution
In general I wrote may api keys just inline in code, sometime declare them split it into two parts for safety. I am using a brain factor;)
let's say you API key xxx-xxxx-xxxx
I code the string xxx-xxxx-xFFF which as you see has same length as right key, somewhere in other method I cut las FFF and append right xxx postfix.
If you have a paranoia you could do it in different classes that defined in same file for convenience but stays alphabetically different places like AStoredKeys TheRightPostfixes that somehow hides your approach from disassemblers.

Honestly there is not much you can do. Literals are probably the best choice, but consider that you really don't know who will have a device and what they are doing with it. It's safe to assume that any talented engineer will be able to get to the keys and code on the device. Even if you protect your keys, there are apps, like screen scrapers and other things than can really get information. Obfuscation is not a good long term practice and good engineers can figure their way around this... it just slows them down. You do have control over your server, so focus on keeping that solid.
In general instead of thinking of securing your keys, think more about limiting information and access.
In regards to data, minimize private data to be received. For example, credit card numbers are never displayed and only the last 4 digits are stored. Or in the case of a banking app, only account balances are displayed, and they also offer two factor authentication (with an image for example). If a device is compromised, while it would suck to have a person's balance known, it's not the end of the world.
This also tends to be good corporate practice as it keeps you safe from any allegations. A person can't allege that information was compromised if you don't have it in the first place.
With access, limit what an app is capable of doing. Firewall it in a sense. Or provide other authentication steps, like SMS verification, two factor authentication. You can also let the server do the secure tasks for you. In the case of banking again, instead of allowing unlimited transfers, limit the number of transfers or the amount. Limit the accounts to which it can be transferred.

You could keep the password separately, in a file on an encrypted disc, or encrypted USB stick. Your code would just retrieve the appropriate file from secure storage. All an attacker would see in your code is the name of the password file.
If that is not practical, then you could XOR encrypt the password in your code. Your application will contain text strings like: "Please enter your password." That doesn't look like a key, but you could use that string as the XOR key to encrypt/decrypt the password. This is more vulnerable as an attacker would see the XOR key you are using in your code and be able to decrypt for herself.
Whatever method you use, do remember to overwrite the variable that holds the actual password before it goes out of scope.

Related

How to use SpringboardServices to get notifications count of an app ios

How can I get notifications count of another app into my app by using SpringboardServices and SBSPushStore?
I'm trying to show notification count taken from whatsapp into my app so I was searching around and one thing is for sure that it is possible but I didn't find any approbate way on how to do it.Here is the question which answers it but I didn't get it. How to do it? Can someone please share the step by step procedure.
Based on the question I was able to find the code which can actually lock you iphone using SpringboardServices but I don't know how to use it for SBSPushStore?
void *SpringBoardServices = dlopen("/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices", RTLD_LAZY);
NSParameterAssert(SpringBoardServices);
mach_port_t (*SBSSpringBoardServerPort)() = dlsym(SpringBoardServices, "SBSSpringBoardServerPort");
NSParameterAssert(SBSSpringBoardServerPort);
SpringBoardServicesReturn (*SBSLockDevice)(mach_port_t port) = dlsym(SpringBoardServices, "SBSLockDevice");
NSParameterAssert(SBSLockDevice);
mach_port_t sbsMachPort = SBSSpringBoardServerPort();
SBSLockDevice(sbsMachPort);
dlclose(SpringBoardServices);
The answer to that linked question you commented on implies that you don't need any framework, as long as your device is jailbroken.
You simply load the plist file located at /var/mobile/Library/SpringBoard/applicationState.plist. The format of that answer is a bit broken, but I assume the > are meant as indicators to explain the inner structure of the file (i.e. key values).
So from that I assume it's a dictionary, you can load it by
NSDictionary *plistFile = [NSDictionary dictionaryWithContentsOfFile:#"/var/mobile/Library/SpringBoard/applicationState.plist"];
NSDictionary *entryForYourApp = plistFile[#"com.app.identifier"]; // obviously you have to use the identifier of whatever app you wanna check
NSInteger badgeCount = entryForYourApp[#"SBApplicationBadgeKey"];
You probably want to inspect the file yourself first (so set a debug point) and make sure its structure is like I assumed, the types are correct and so forth (not to mention it exists, Apple sometimes changes stuff like that and the other question is already several years old).
In general be aware that you can only do that, as said, on a jailbroken device. Otherwise your application simply doesn't have reading access to the path /var/mobile/Library/SpringBoard/applicationState.plist. Or to anything outside its sandbox, for that matter.

iOS: Storing Non-User password

I need to store third-party username/password in my iOS application, what is the best and most secure way to do this? When my app first runs, it will need to talk to Google's Picasa to download private pictures to use for the app. To talk to Picasa, I have to provide my username/password and storing in the code is not secure at all.
I've search the web, I see Keychain came up a lot, but how exactly do I pre-load my password into keychain?
Is there a configuration file in xCode somewhere to store passwords needed for web-services?
Thanks
Think that you need to store the password in encrypted form. Pick some encrypting algorithm, generate the encrypted details. And in code have some method to decrypt it when needed.
You just don't want someone who would read your code as plain text to see the password.
Think that something as simple as splitting the password into separate strings and later joining them could be enough.
Here for example You have encrypted in code "My1Password":
#define R1 #"My"
#define R2 #"Password"
+ (NSString *)generatePass{ return [NSString stringWithFormat:#"%#%#%#, R1, #(1), R2]; }
This is a response to krzysztof above:
I'm in a catch-22 situation here as I can't seem to grasp the concept of feeding the password as parameter to another function. Aside from avoid others reading the source code in plain text, can't hackers obtain the binary file and reverse engineer to read the password in the source code (R1 & R2 in this case)???
Back to encryption, lets take the following line of code which Encrypt/Decrypt data:
NSData *encryptedImage = [RNEncryptor encryptData:imageData withSettings:kRNCryptorAES256Settings password:#"A_SECRET_PASSWORD" error:nil];
NSData *decryptedData = [RNDecryptor decryptData:data withSettings:kRNCryptorAES256Settings password:#"A_SECRET_PASSWORD" error:nil];
This is where I'm stuck... where do I store A_SECRET_PASSWORD?

Data encryption with AES

I'm building an app that will communicate with a server (php), and this communication (probably will be with json) i want to encrypt. After a lot of searching and reading i found the AESCrypt-Objc project.
While testing the encryption (i'm using a web tool AES Encryption test) i found that in the encryption result i'm missing 16 byte of data.
Here's the example i'm using
In the AES project:
String to be encrypted: "The quick brown fox jumped over the lazy dog".
Password: "12345678901234561234567890123456"
The result:
<7eda336b 82f3e279 ae7638fe cccfffc6 5fbef8da 6df76d97 67d8cfa8 5bce2ae9>
My Code:
self.strnToBeEnc = #"The quick brown fox jumped over the lazy dog";
self.appKey = #"12345678901234561234567890123456";
NSData *data2 = [self.strnToBeEnc dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"%#", data2);
NSData *s2 = [data2 AES256EncryptedDataUsingKey:self.appKey error:nil];
NSLog(#"%#", s2);
WEB Tool:
Same string and password
The result:
<7eda336b 82f3e279 ae7638fe cccfffc6 5fbef8da 6df76d97 67d8cfa8 5bce2ae9 ca2ed34a 48f85af2 909654d5 b0de0fb7>
As you can see i'm missing some bytes...:)
I've tried adding to the buffer in the algorithm, but with no success.
Any advice?
Thanks
(if the question is not Detailed enough please let me know)
I know you were trying to avoid this but I think you might need to spend some time in the source code of AESCrypt-Objc as I suspect it is somehow not encrypting the last block.
Step into the code and see if you actually get to the CCCryptorFinal call, and note its results. This can be found in the AESCrypt-ObjC/NSData+CommonCrypto.m _runCryptor:result: . Another thing to look into is the default padding type they are using which appears to be kCCOptionPKCS7Padding this will also have an effect on your ending bytes.
Do your testing first with non-arbitrary length bytes that are multiples of the AES block size, then once you have validated that move on to the variable length ones you have here.

iOS AES encryption wrong result

Here is how I encrypt the string:
+ (NSString *)encrypt:(NSString *)message password:(NSString *)password {
NSData *encryptedData = [[message dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptedDataUsingKey:[password dataUsingEncoding:NSUTF8StringEncoding] error:nil];
NSString *base64EncodedString = [NSString base64StringFromData:encryptedData length:[encryptedData length]];
return base64EncodedString;
}
The plain text is:
{"roomID":"{\"array\":[\"949156\",\"949157\"]}","duration":15,"link":"","type":"text","thumbnailBlobID":"","posy":103.6809424405021,"text":"Aa","className":"Message","originalBlobID":"","datetime":"20140319214528457","selfDestructive":0,"userID":"949157","posx":1.347154229880634,"status":"normal","entityID":"20140319214528457and949157and{\"array\":[\"949156\",\"949157\"]}"}
This is what I get
gXqxfDhImRD7S20lUdYuCPAlXfqRnG6xk4w4K5Op/WnYMh6VgJUUqMifK2vHkUpAbnZ+wKdSWjfzU1PuOwvJ4dJ9EiHwjeyyorezFNG6eylYcOvMWNeU6+5Z9XxfcFngqhmxM6k1lf7bkttTu0FnEHad/czFgiMVTy60DJpFMLSODkKEVezqQB9s/f3Qy/B6+sF5Hs5E0FDn7kU6Jtm6mLkFjGzDCXTdFXNjdussbkTL8C1gcOnn4hrNkqQKb82MgqqYf8sVgs4FVIjsmoJd0ALY8y/5QbBkgc6ZyB4aOQPPx/u4HS3F7HXHkIkkAjZS/hiHQBRyfwCvi2uwFedno5twYogNW56pSMQqBeJBxBAhPMpXzb51853GLP4bCotGtOyEfU96x5kWHDOR5QA2WhYZkB3AALDJ2kfqzWR8iOKHo3zE6DCQ7aH0RwEFlNPi8vsNwvUqtQ7nUODA5lUMYah6W2rfDh/em8BD8dGF5J6IUTIlSerx8wWPA9bn/SxO
From website http://aesencryption.net (256 bit)
(Which i assume to be the correct answer
5MdV0TelF++/8Cy9bnkeah0nQ5JbC04CEdCcHfdlavQtZaxg3ZSXklp9yXbeP05hcIeQDgFcMr9NlD6aKhjBL3Xh70ksYqc6Xv5BZvCbXrvO4ufAf4gjmDRQr9DYSbjFct6N82fFGDtrcuFm36Zv+QAQtR/scT86A++Vn/EBlPwFb7ZmxlMPkJWjQ98ObreXHeKkZ8f2npMKfJ0i36nIZ8CZeL0EYeg/njo9ykPTfm9wfKieqlIICn1qNZAXE//P9hTleW/GNs5+ET2gxNSCmdO+ByUB9Q3sZ/+57qXbsfCxHr8dsuBrsbRI+cVIXyquQL1IC/zuz3G3fcyoiLrD/PnFtV5z5XR0hpUiU8JjovjYwyXaBfyTBnO71zxmdoZdsyPwA1LQO0pedn8UsICT2KbfBKwuumW2CJPexbnMmVzpIJ/VPISikdg18V3rdJqiPMIb4Zq2PGKO0Wtq1dCTMusTv/ZnqxgVQFQlUivgBqtnOLCDaMAGL636NXda95V2
There is no single standard way to apply AES, or standard data format for the output. AES requires a number of helpers when used on data that is not exactly 16-bytes long, and they can be configured in different ways. I have no idea how the aesencryption.net tool is applying these helpers; it doesn't say. If AES256EncryptedDataUsingKey: is the particular piece of code I assume it, it applies them very poorly (it's very similar to the code I discuss in Properly Encrypting With AES With CommonCrypto). I would not be surprised if aesencryption.net does something different.
If you have a piece of plaintext and a key, and you pass it to an encryptor twice and get the same answer back, then your encryptor is broken. A correct AES encryptor (for almost any common use of AES) should always return different results for the same plaintext+key (otherwise an attacker can determine that two plaintexts are equal, which breaks the security proof of AES). In the most common case, this is achieved by having a unique initialization vector (IV). For password-based AES, you also include a random salt. So even if these were good implementations of AES, you wouldn't expect your results to match.
Is it possible that the escape characters (the back slashes) are being interpreted differently in code versus via the web? The bottom line here is I would (in code) decode what you just encoded and you should come out with the same as what you put in. This is probably the test you want to conduct. Hope this helps. Also see comment below from #RobNapier

Best Place to Store Included AWS Credentials in an iOS Application

I plan on using the AWS SDK for iOS for an upcoming project. I need to store credentials for AWS with the packed application. Where is the most secure place to place them? I know that storing them in a pList would be a bad idea. Is it better to just 'hard-code' it into a class that will be compiled? Is there any risk there?
I believe that completely hiding the credentials is theoretically impossible. That is, if your compiled code can read them, then in theory so can anyone with access to the compiled code. But imperfect security is still worth something. I'd guess that most attackers would just look through the binary for strings that look like secret keys, and not go to the trouble of decompiling the code and trying to interpret how it works, so one way to hide the credentials would be to store them in an encoded form, then decode them as needed. This way the decoding algorithm becomes your key, and an attacker would have to find and understand it to extract your credentials.
Here's a fairly simple way to do it using a random XOR mask. Replace the following bogus password with yours, and remember to keep the NULL terminator (\0) in place. Compile and run this code as a standalone program:
#include <stdio.h>
#define PAD_LENGTH 32
int main() {
int i;
char c;
// start with the password
char password[PAD_LENGTH] = "My AWS Password\0";
// make a random pad to encrypt it
printf("PAD:\n{");
char pad[PAD_LENGTH];
for (i = 0; i < PAD_LENGTH; i++) {
c = arc4random() & 0xFF;
pad[i] = c;
printf("%#02x", c & 0xFF);
if (i < PAD_LENGTH - 1) printf(",");
}
printf("}\n");
// make an encrypted version of the password
printf("KEY:\n{");
for (i = 0; i < PAD_LENGTH; i++) {
c = pad[i] ^ password[i];
printf("%#02x", c & 0xFF);
if (i < PAD_LENGTH - 1) printf(",");
}
printf("}\n");
return(0);
}
Then copy the generated pad and key into code like this (which will actually get included with your app):
#define PAD_LENGTH 32
char pad[PAD_LENGTH] = {0x83,0x26,0x8a,0x8b,0xee,0xab,0x6,0xed,0x2e,0x99,0xff,0x23,0x7f,0xef,0xc8,0x8,0x6b,0x8e,0xa4,0x64,0x6d,0xb,0x7,0xd2,0x6a,0x39,0x60,0xa4,0xa9,0xad,0xea,0xb8};
char key[PAD_LENGTH] = {0xce,0x5f,0xaa,0xca,0xb9,0xf8,0x26,0xbd,0x4f,0xea,0x8c,0x54,0x10,0x9d,0xac,0x8,0x6b,0x8e,0xa4,0x64,0x6d,0xb,0x7,0xd2,0x6a,0x39,0x60,0xa4,0xa9,0xad,0xea,0xb8};
for (int i = 0; i < PAD_LENGTH; i++) {
key[i] = key[i] ^ pad[i];
}
NSString *password = [NSString stringWithCString:key encoding:NSASCIIStringEncoding];
Since this is on a public forum, you might want to change a few things, like making the pads a different length, splitting them up and rejoining them with code, reordering them, etc. You could also store the pad and key in distant parts of the code. A truly skilled and dedicated attacker is going to be able to find your password no matter what, but the basic idea is that most people scanning the binary for a password will not find it as such.
Have you looked at the Data Protection API?
What are the new "iOS data protection APIs"?
There are various options depending on your security needs.
This question may help also.
Data Protection on iOS
The video from a conference this year was useful.
http://developer.apple.com/videos/wwdc/2010
you should use AWS Identity and Access Management (IAM): http://aws.amazon.com/iam/
you can find more information about AWS Credential Management in Mobile Applications on http://aws.amazon.com/articles/4611615499399490

Resources