Only a short question here, I would like to know the best place to put my registration code for the user that I get back from the server. I am encrypting it as seen here.
//encrypting
NSString* strToEncrypt =NewPINField.text
NSString* theKey = #\"KeyKeyKeyKey\";
NSData* dataToEncrypt = [strToEncrypt dataUsingEncoding: NSUTF8StringEncoding];
NSData *encryptedData = [dataToEncrypt EncryptWithKey: theKey];
NSLog(#\"Encrypted data: %#\", encryptedData);
//decrypting
NSData* encryptedData = (NSData*)[profileData objectForKey:#\"PIN\"];
NSString* theKey = #\"KeyKeyKeyKey\"; //notice this is the same as above. It MUST be
NSData *decData = [encryptedData DecryptWithKey: theKey ];
currentPIN = [NSString stringWithUTF8String:[decData bytes]];
NSLog(#\"Decrypted pin: %#\", currentPIN);
The only other specification is to hide it / put it somewhere no know would think to look.
I need to save state so it needs to be some sort of plist, I was just wondering if there is a way to hide it a little better than just adding it straight to my plist file.
what would you do?
Any help would be greatly appreciated.
If you need to securely store data, I would highly recommend using the keychain. There is a tutorial on creating a basic keychain app here: http://www.raywenderlich.com/6475/basic-security-in-ios-5-tutorial-part-1
You can safely store data in the keychain without worrying about encrypting it first, since that is handled by the OS. But you can if you want to.
When implementing security, never try to hide things where someone won't look: http://en.wikipedia.org/wiki/Security_through_obscurity
Related
All I want is to change every time the NSString townLocation.
Because I take data from an API and I don't want to create different API for different location. Also I know that the "+" that I put on the link is not correct and there is not such think in Objective C but I want to make you understand what I want.
NSString*townLocation;
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://api.openweathermap.org/data/2.5/find?q="+townLocation+"&units=metric"]];
How I must do it ? Im sure you understand that I'm new at Objective C
Thank you
You only need to look into the most basic NSString documentation to find a method that will do that, stringWithFormat:.
NSString *urlString = [NSString stringWithFormat:#"http://api.openweathermap.org/data/2.5/find?q=%#&units=metric", townLocation];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
If you're new at Objective-C, a good place to find information like this is to simply search the internet or the iOS Developer Library for the class in question (in this case, NSString) to find a myriad of resources at your disposal. Another doc to check would be Formatting String Objects, which is linked in the stringWithFormat: section of the iOS Developer Library, to find more info about formatting strings.
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?
What is the best practice to store sensitive(not secure) data on iOS devices?
Where should I store information that user bought something in app? For example where should I store BOOL showAds variable if user bought "Remove Ads"?
I do understand that everything breakable, especially on jailbroken devices, I just asking what is the best practice.
My variants:
.plist in App Documents -- Editable using iFunBox, for example
NSUserDefaults -- Same here, I guess
Keychain -- best variant in my opinion so far
You can store you data in NSUserDefaults using base 64 encoding data to keep safe it.
The code is very simple:
NSUserDefaults *persistValues;
persistValues = [NSUserDefaults standardUserDefaults];
To set data (encoding it using base 64):
// Create NSData object
NSData *nsdata = [#"iOS Developer Tips encoded in Base64" dataUsingEncoding:NSUTF8StringEncoding];
// Get NSString from NSData object in Base64
NSString *base64Encoded = [nsdata base64EncodedStringWithOptions:0];
[persistValues setObject:base64Encoded forKey:#"some_key"];
To get data:
base64Encoded = [persistValues stringForKey:#"some_key"];
NSData *nsdataFromBase64String = [[NSData alloc]
initWithBase64EncodedString:base64Encoded options:0];
// Decoded NSString from the NSData
NSString *base64Decoded = [[NSString alloc]
initWithData:nsdataFromBase64String encoding:NSUTF8StringEncoding];
And if you data is bigger I suggest you uses web services and store it in a web server
Keychain is best option to store sensitive data.
Other than sensitive data below are 2 options :
Small data can be stored in NSUserDefault as its best way as physical file will not be available for changing data.
Bigger data can be stored in database with encryption
I have the first part figured out...
- (void)webViewDidFinishLoad:(UIWebView*) myTapView {
NSString *jsString = #"localStorage.getItem('username');";
NSString *someKeyValue = [tapView stringByEvaluatingJavaScriptFromString:jsString];
// This is where I would start storing it so I can retrieve it later
}
So here is my issue, I need to store the value I just got from localStorage so I can use it again. Problem is I don't know where to start. This code is inside my ViewController for the WebView, so I need to be able to use it in other areas in the ViewController.m file.
What is the best method for storing the info? I would also want the above code to be able to update the value, as it won't always be the same username (people can switch accounts).
There are a few ways to store data on iOS, but it depends on what kind of value you want to store. If it's just a plain string or other "light" data, the best approach is to save it to NSUserDefaults. If it's an image or video, you may want to consider archiving it using NSKeyedArchiver. Otherwise, if you want to build a complicated data model, use Core Data.
Here's a good post on NSHipster that describe in detail pros and cons of each approach.
According to your code, you want to store a string. I'd go with NSUserDefaults in this case.
Use NSUserDefaults to store UIWebView local storage value as follows
- (void)webViewDidFinishLoad:(UIWebView*) myTapView {
NSString *jsString = #"localStorage.getItem('username');";
NSString *someKeyValue = [myTapView stringByEvaluatingJavaScriptFromString:jsString];
// Store your Username in iPhone persistence variable and use it later in the application
NSUserDefaults *userdefault = [NSUserDefaults standardUserDefaults];
[userdefault setObject:someKeyValue forKey:#"username"];
[userdefault synchronize];
//use of User default
NSLog(#"User name %#",[userdefault valueForKey:#"username"]);
}
What is the easiest and fastest code to do a conversion between NSData and a base64 string? I've read a bunch of solutions at SO and mostly they involve in adding another class etc. I found a great solution here but it's too complex.
Scroll down to the Conclusion section on the page you linked and download the provided NSData+Base64 files. Its the best solution I have seen so far and is incredibly easy to use. If you can learn anything about Cocoa, you can learn to use that project.
Example
NSString *originalString = [NSString stringWithFormat:#"test"];
NSData *data = [NSData dataFromBase64String:originalString];
NSLog([data base64EncodedString]);
The above will print out the original string after converting it to base64 and back to a normal unencoded string.
As of iOS 7, NSData now directly provides this functionality with the new methods -base64EncodedDataWithOptions: and -base64EncodedStringWithOptions:. (The options let you specify that the string is/should be line-wrapped, the better to deal with email, and user-facing displays.)
You don't need any custom implementation. Creating base64 from NSData is shown in other answers. There is opposite direction. From Base64 string to NSData:
NSString *base64Encoded = #"some base64 string";
NSData *nsdataFromBase64String = [[NSData alloc] initWithBase64EncodedString:base64Encoded options:0];
I ended up using this same class as provided by SUDZC
implementation was easy first I did an import
#import "NSData+Base64.h"
then I was able to call my data.
NSData *data = [[NSData alloc] initWithData:[NSData dataWithBase64EncodedString:strData]];
Be aware that there are more Base64 formats.
For example JWTs use a URL safe format.
Or you may take a look to the (quite new) CryptoCompatibility sample project, I think there is a wrapper class for base64 operation. It is a MacOS sample but it uses the library libresolve.dylib with I think is available on iOS too (is see it at least here in iOS7).