I have a string encrypted using RNCryptor v2.2 ObjectiveC library.
After encryption it is stored locally on iPhone.
When want to get the string back, before decryption, I want to make sure that the encrypted is not tampered (like manually changed a character).
How can I verify this?
Thanks in advance!
The theoretically correct answer to your question is that whatever you do in your app locally on the device, you will not be more sure whether your data has been tampered or not compared to doing nothing. You will need to use an external, reliable agent such as a https web server to store some information about your data.
Let me explain this briefly. iOS already gives sufficient protection to the data of your app with its data sandboxing model assuming that the device of the user in not jailbroken. This means that there is no way to alter the private data of your app (saved in the standard Documents, Caches, etc. folder of your app). On the other hand a malicious user who wants to modify the encrypted information stored in the private folder of your app, can jailbreak the device. In this case he will have access to everything and can read and write any private folders.
Some could say that you can create a hash or a digital signature of your data and store it on the device. But if the device if jailbroken the intruder would have access to everything, including the binary code of your app (Objective-C can be reverse engineered without too much effort) and so the hash generating algorithm, the salt or the private key of your digital signature. So he could easily manipulate the digital signature or the hash as well.
You should evaluate the risk of your data being tampered. How much effort worth tampering your data? If you are storing banking information and count about 1 million of users, you should take seriously the risk that somebody could jailbreak the device, reverse engineer your app and tamper your data. If you are storing session tokens of a photo-sharing app, maybe you can just leave it as it is and trust in the sandboxing of iOS. Also it is very important that jailbreaking the device needs active participance of the user so it is not possible to do it remotely, without the consent of the user. This means that the data can not be tampered without the consent of the user.
If you really need to protect your data then the only way is to use an external service that you trust and that can provide your an external security regarding to the device. You could send your sensitive data to a web server through https, let the web server sign it with its private key and resend to you the signature that you can store calmly wherever you want. Every time you need to access to your sensitive data you could verify the signature of the data (and the validity of the signature with the public certificate of the server). As the private key is stored on the remote server, you can be sure that nobody can access it and it can not be used to sign a tampered data.
RNCryptor includes an HMAC to detect this. If the ciphertext is modified, it will not decrypt. You'll get an error ("HMAC Mismatch").
Related
I have static key in my iOS application. By using that key I am encrypting credit/debit cards and sends it to server for future use. And I am using same key for decryption of card.
Now I can't use dynamic key by any key generation algorithm as I want to decrypt my card later on. So, Every time I require same key.
So, My question is how should I store my key or where I should store my key as it'll be most secure? or Can I manage this stuff by generating dynamic key every time? If yes then how?
Many iOS applications like Amazon, Uber etc are storing the card information in their server! How they people are managing this stuff?
Any help will be appreciated! Thanks!
If you need to ask this question then you are already breaking PCI compliance. Your customers credit card information should never touch your server, encrypted or otherwise. Most payment gateways handle this for you. There is very little reason why you should be doing this yourself.
If you do need to handle this yourself, and there are very few cases where you do, simply symmetrically encrypting the card information in your app is not the way to do it. Literally anyone who can download your app can decrypt other customers credit card information.
The correct approach would be to transport card information to your server secured with TLS, then encrypting and storing the key information in a HSM server side. If you can't manage this, then you are not PCI compliant and will be legally responsible.
If your business operates, or has service available to customers in the EU, then you could suffer very heavy fines for poor handling of consumer credit card information.
I am new of iOS swift 3 development. Now, I am working on a project which needs encryption, message authentication code(MAC) and Hashed-base-MAC. These algorithms require secret keys. I know that it is a bad practice to hard-code the keys inside the code, like:
let key = "secretkeyabc123"
Searched and read some articles like:
In iOS, how can I store a secret "key" that will allow me to communicate with my server?
Since other people may perform reverse engineering, I am finding a way to protect my keys. Requirements:
No hash the key. Time allows to crack it, or with hashed table and dictionary
May not connect to Internet (My app. is an offline app. If your answer needs to connect to Internet. Yes, please point it out. I will think about it)
It is a static key. It may change monthly
It is a symmetry key.
Codes, concept or other things are welcome. Thanks!
Don't store the key at all. Perform a Diffie-Hellman key exchange to start an asymmetrically encrypted channel, and use this channel to send across a symmetric key to the client, which can be used for subsequent client use.
Check iCloud Keychain (based on your tags [ios], [swift], [key]).
It functions as a secure database that allows information including a user's website login passwords, Wi-Fi network passwords, credit/debit card management (though without CVV), and other account data, to be securely stored for quick access and auto-fill on webpages and elsewhere when the user needs instant access to them. They are always stored encrypted using 256-bit AES encryption, are stored on device and pushed from iCloud between devices, and only available on a user's trusted devices.
I have a mobile app (React native) that I am using with ParseReact with and have it so the user can immediately send data to parse inside the app. How can I lock this down so that parse.com will only take data from users with the APP installed?
Mitigations I have thought about:
Using ip address, geolocation, deviceUUID (per app)
Possible encrypting traffic to parse to hide something secret?
I know 98% of users will likely be nice and not fake this but I'm worried about the hackers
The short answer is you can't. If you give public access to any of your classes, anyone can write to it and you will have no control on who is reading the data. You can make it difficult for someone to send write requests outside of your app by embedding a signature in your app and forcing all your public writes to go through cloud functions. You use the signature to sign every write request and send the signed token as a parameter to your cloud functions where it will be verified before you accept a request. But remember a cracker can easily find your signature in your app binary so this not bulletproof.
In iOS application i have to make user's login safe and secure and user can login from different iPhones having same application downloaded. Application should work in offline too. So which method should i implement?
I searched and got RSA encryption in which there is private and public key method but i can't figure out how i implement it in application?whether i hold both keys in server and client side or who get which key? And how can i make only one key generation for every application downloaded? As data should roam securely between client server system.
Is there any other mechanism which i should consider implementing in my problem?
You don't need to perform any encryption. Just store the passwords in the keychain, which has stronger encryption than anything you could possibly implement — as it's integrated into the Secure Enclave which has no public API other than keychain and already uses RSA encryption, among other things to make it even stronger than just that alone.
If the user enables iCloud KeyChain syncing, then the password you store there will be synced across all their devices.
Your application will work offline.
If the user has a weak passcode to unlock their device, then the encryption will not be very good - it can probably be cracked in under an hour (although this information is old, and may not be valid for modern hardware). The best security practice is to disable "Simple Passcode" and use alphabetic characters + digits. It doesn't need to be as strong password, just something short and alphanumeric is fine (the iPhone is a special case, and handles weak passwords better than most security systems). If the user has a finger print scanner available, that can be used to avoid having to type their password in regularly. This is quite secure, contrary to early reports otherwise.
If the devise has no passcode at all, then there is no encryption and it is impossible to implement protection. In that case your only option is to store your secure data on a remote server, and never ever allow the device to access it. Or else just hope nobody steals the phone. Without a passcode/password, it is impossible to store anything securely on an iPhone.
It sounds like you want a single device that will be shared by many users? If that's the case you cannot store the password on the device. It is impossible to achieve security unless there is a passcode and the passcode must be secret, anybody who knows it will be able to bypass any encryption you implement.
As you know many apps use keychain to save user login name and password, but is it really safe? especially on device jail break mode. So another solution is to use Outh2 protocol to save those confidential infomation on server side which needs many changes on both client and server side (for my app).
How do you guys handle this tough issue? Anyone who knows please share and thanks in advance.
Keychain:
It has two level encryption options
lock screen passcode as the encryption key
key generated by and stored on the device)
But when the device is jailbroken its not safe too.
oAuth:
Eventhough you store credentials in server you'll have to save the OAuth TOKEN in client side there is no place better than keychain to store it in client side.So now comes possibility of extracting the TOKEN on jailbroken device.
As far as I know in most apps they use one of these approaches.
If you need those data to be very very secure.
Suggestions:
Store OAuth token in server not in client
Store the Encrypted Credentials in Keychain and store the encryption key in server.This approach would be easy for you since you said adopting OAuth is hard for you.
Note:
There are some open source libraries available which detects if the device you run or app is cracked if so you can take action like deactivating TOKEN,deleting critical resources,locking app etc.