I'm using a UIWebView to display a webpage. I'd like to know if it's possible to encrypt and decrypt cookies stored on an iOS device. I'm using NSHTTPCookieStorage to store my cookie but I noticed that is stored as cleartext in a property list file.
I discovered that it's stored in a path similar to:
Root/User/Applications/ASDSDF234ASDRSDF234/Library/Cookies/Cookies.plist
I would like to keep private information, such as usernames, secure.
There is a sandbox mechanism in iOS system for security, so your app data could NOT be read by other apps. So I think you can keep private information in cookie.
Only for the jailbreaked iOS device, there will be the security problem. I think you can encrypt/decrypt your cookie data both in server side.
Related
When we configure Server-to-Server Notifications, we Specify our secure server's URL in App Store Connect and the apple server communicates on that URL. but is there a way to authenticate this request?
It is not safe to keep url open without authentication
in case of PlayStore we can use GOOGLE_DEVELOPER_API_KEYFILE_JSON for authentication, but how to do this for iOS server-server notification?
As the comments have already clarified that there is no built in way.
So, here is my work around of this problem.
Apple sends password in the notification which is App secret key which ideal should only be known by API and Apple.
And to verify receipts coming from the App this password must already be stored somewhere (configuration?) in the API.
So I suggest to check whether the password in request matches with the one stored in our API?
If yes then this is a valid request.
If not then it may be sent by a hacker.
My only concern is that does this App shared secret key aka password change? by Apple or developer? If not than this is the solution.
One way to do it is to use Basic auth. As you cannot specify a header you can use the url format: https://username:password#SERVER_ENDPOINT. This will automatically encode the username:password and construct a basic auth header with the encoded string.
Source:
https://en.wikipedia.org/wiki/Basic_access_authentication
I need to store an encryption key within my app, so that it can use the same key to encrypt and upload data, and download and decrypt data, from a public store. That way, the data can't be read by any other party in between.
What I'm concerned about is the potential for somebody to hijack my app. Once my app has been archived, would it be possible for someone to read a hardcoded encryption key held within the app?
If the key is in the app bundle there is a chance it can be discovered and doing this is not secure. As #Cristik states authenticate the user to the server and download the key at that point.
To secure the key the best you can do is to save the key in the Keychain.
Protecting against the owner of the device is very difficult and falls more under DRM.
Protecting against an non-owner depends on the owner having set a good passcode/password.
Protecting against data in transit (upload/download) is easy, use https, ensure the server is current (TLS 1.2 and Perfect Forward Secrecy) and pin the server certificate in the app.
Update:
In the ipa only the executable files are encrypted so other files can be accessed from the download. If a file is encrypted the attacker will need the encryption key and that can be strong: random bytes.
But the app needs the encryption key so the problem is how can the app know the key and not an attacker. Encryption does increase the work factor be the need to obtain the key.
There are disassemble tools so if the key is in the code it can be found by an experienced attacker.
If the key comes from a server it is not coded into the app so the work factor again increases. A MITM attack can be used to see the key in transit and pinning the certificate and using current https best practices can mitigate this attack vector.
Finally the key is in RAM memory at the time of decryption and can be found but again the work factor is increased.
In general what is necessary to protect data at the highest levels is complicated, requires special hardware and physical security.
Bottom line: determine the level of attacker you are defending against and the value of the data; code to that level. Do not underestimate the attacker.
Instead of storing the encryption key within the application bundle, you can request it from a server via a secure connection (HTTPS), and then save it in keychain for later retrieval.
You can add more security layers to the https connection by adding SSL pinning or/and other security measures.
Plus, you can generate different encryption keys every time the user logins, and if the store API supports it, you can invalidate all keys generated for a user if for example his phone is stolen.
I'm working on an iOS app where I need to store user's credentials for a 3rd party service on my server. (For example, storing IMAP login/password so that when they sign into my app it fetches from their IMAP server, so my server doesn't store their email)
I am not considering OAuth since not every email service provides OAuth. To do this I was thinking about the following option:
User enters username/password to sign into MyApp (MyApp server implements standard security measures, meaning it stores hashed version of the password and not the raw password, so MyApp server does not know what a user's password is)
Once signed into MyApp, MyApp stores the raw password into local keychain.
User 'connects' their 3rd party email account by signing into the 3rd party email account.
When the 3rd party email account successfully signs in, MyApp encrypts the email's password using the MyApp password (which is stored in keychain from step 2)
The encrypted password is stored on MyApp's server as "emailPassword"
From then on, whenever user signs into MyApp, MyApp fetches the encrypted "emailPassword" from MyApp's server and decrypts it back to its original form using the MyApp password stored locally on the user's keychain (which was used to encrypt in step 4).
Using the raw password decrypted from step 6 MyApp fetches emails from the 3rd party email server.
I am new to encryption so not sure if this is a safe (or even possible) option. Could anyone help? Thank you.
[UPDATED] Updated to clarify concepts and changed "encoded" to "encrypted"
You should rather say "encrypt", not "encode". Encoding is a mechanism which translates data using some set of fixed rules (algorithm). Base64 is an encoding, so is urlencoding. Encoding doesn't provide ANY security.
Encryption, however translates cleartext to ciphertext using an algorithm that uses crypto keys. Without knowledge of the key, the reversion of the ciphertext is very hard. (never impossible)
Okay, regarding your example:
It is implementable, but even though there are some attacking chances.
At some point in runtime, MyApp knows the cleartext password. At the time it is decrypted. The plaintext password then lies in RAM and could possibly read out by malicious software with respective permissions (root malware e.g.)
Also you need to make sure to use suitable algorithms in the right mode. AES-256 in CBC is more secure than in ECB mode. Then you also have to think of how to convert the password into a crypto key. Would not be too secure if you just used the password. Then you should also use a trustworthy library, no library from an unknown guy or so
Well, these are just some thoughts. You should get a little background knowledge before struggling with encryption. There are many options and you should really know, what you do.
I have gone through apple developer videos on Security they have mentioned to use ssl https certificates and keychain to deal with security.
My iOS app will be giving access to sensitive paid files. so hackers should not get access to these files. I will be using in app purchase, so that user can buy these file.
1) My first question is: Should i host my files on apple server (Hosted Contents) , is the apple to client communication secure enough or should i implement my own server code with certificates and ssl authentication.
2) i want to know or get idea on how to encrypt files using private key on my desktop machine and then upload it on my server. When asked for by my iOS app pass the public key and encrypted file and save the public key in Keychain for further use. I want this feature so as to save the file on disk without anyone getting access to it by jailbreaking or other hack.
3) What should be used as public and private keys and what type of encryption to use. Currently i have come across AES looks good enough but is there a better way? Can certificates itself used to encrypt data or pass keys?
4) Which certificate authority to contact for most secure certificates.
Thanks in advance...
EDIT:
Main purpose to achieve is to download pdf and that pdf should not be accessible to user outside the app.
1) I have decided to use root certificates from CA and https to transfer content, to avoid MINM.
2) On app side i will generate public private key pair.
3) Save Private key in keychain.
4) Send Public key to server.
5) Server will encrypt pdf using MAIN-AES-Key.
6) MAIN-AES-Key will be encrypted using Public key sent by app.
7) Encrypted-pdf and Encrypted-MAIN-AES-Key will be sent to app.
8) Encrypted-pdf will saved to disk with secure write options just incase.
9) Encrypted-MAIN-AES-Key will be saved in keychain.
10) To decrypt pdf: Private key generated by app will be used to decrypt Encrypted MAIN-AES-Key and MAIN-AES-KEY will be used to decrypt pdf.
11) Finally will be trusting Apple-KeyChain to keep Private-Key secure.
The solution is unnecessarily complicated. The more complicated, the less secure due to more potential errors/over-sights.
Do use https with a CA signed certificate
To avoid MITM pin the certificate on the app side
There is no need to further encrypt the data being sent over https
Encrypt the file on the device and save:
Create an encryption from random bytes
Save the key in the Keychain
Create an iv from random bytes
Add the iv to the beginning of the encryption buffer
Encrypt the data with AES, CBC mode and PKS7 padding into the buffer following the iv
Save the data into a file the the app file area, possibly under the Documents or Library directory
Decrypt the file on the device and use:
Get the key from the Keychain
Read the encrypted data file
Get the iv from the beginning of the data
Decrypt the data starting just past the iv
Do not ignore the server
Use two factor authentication.
Properly hash with a salt any passwords
Use good user authentication
For the app data encryption consider using RNCryptor instead of writing the encryption portion yourself.
I need to protect my API for CSRF on post and put requests.
To do that, I think the mobile device (example iOS) need to send to the API server (node.js) a token. This token must be encrypted and contain a JSON data that will be decrypted server side.
To decrypt the data, the mobile device use the same secret key that the sever know.
For example : {_csrf: 123456789} will be decrypted from the token sent via the mobile device and checked by the API if it match.
Is it the right way ? If not what is the right way ?
How I can encrypt a Jon data on iOS and decrypt it on node.js ? (JWT Token does not have library for iOS)
Can you provide me a example code to encrypt data on iOS et decrypt on node.js ?
Just use https, it encrypts everything, even any query string.
The content is encrypted with a random symmetric key and that key is encrypted with a asymmetric key from the certificate. Additionally the symmetric key has a short lifetime. Additionally you do not have to implements and encryption routines.
Also note that iOS9 will by default require https to be used for all connections, any http connections will need to be white-listed in the plist.
If you do your own encryption you immediately have a problem sharing the encryption key between the device and the server. This is not an easy problem to solve.
When accessing the API from a browser page, to protect against CSRF, you can send a token in HTTP headers, for example, X-CSRF-Token, or, use a cookie.
For example, have your server send the CSRF token in an HTTP response using the X-CSRF-Token header. You can have your page send it back in the JSON on the POST or PUT. Or have your page read it from the cookie and put it into the JSON.
(HTTPS from the browser will not protect against CSRF, since any script on any other site running in the same browser can POST to your HTTPS server freely. Your page needs to have a token that no other page in the same browser has access to.)