How do you secured a key into your iPhone application?
I have an API key that is used by the client application, and do not want anyone to see it, only the application should be able to read it.
1) how do I safely store this in my application? storing it into a variable? is good enough?
2) What happens if someone decrypts my application? (Is that possible?)
There's a lot of questions here so let me answer one at a time:
How do you secured a key into your iPhone application?
I assume that you are trying to secure it from the user of your application. This is impossible unless you are using a trusted computing platform, ie. a platform that can be trusted to not obey orders from its owner (sometimes called treacherous computing for that reason). iPhone is not such a platform to my knowledge.
I have an API key that is used by the client application, and do not want anyone to see it, only the application should be able to read it.
If your application can read it then the owner of the platform that your application runs on can read it as well. (The exception would be a trusted computing platform - see above.)
how do I safely store this in my application?
You can't.
storing it into a variable?
You might.
is good enough?
No.
What happens if someone decrypts my application?
Then he gets your key.
Is that possible?
Yes.
If you don't want your users to know your key then don't give it to them in the first place. Set up a proxy server that your application would connect to and keep your secrets there.
There's an old saying that every secret has to be treated like a public knowledge unless it's known by no more than two people. This applies to software too.
Consider storing the key in the iPhone's keychain repository. Take a look at the Apple provided keychain sample app here:
http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Introduction/Intro.html
Hope this helped. Good Luck.
I agree with Greg Thompson, Apple recommends the use of the keychain to store secure data such as credentials.
By the other hand there is a couple of articles around the web that says that the keychain is no longer "the safer zone", because some people were able to decode its data (and pretty quick).
With iOs 4.0 and later, some improvements about security where made, that is called Data Protection (you can google it like: iOs data protection).. if you are interested in this topic, you'll find the Session 209 - Securing Application Data from WWDC 2010 Session Videos very interesting ... You can get this video for free via iTunes store - iTunes U
Hope this helps
Related
Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary? This app will be distributed on Google Play and the Apple App Store so it should be implied that someone will have access to its binary and try to reverse engineer it.
I was thinking something involving the app signatures, since every published app must be signed somehow, but I can't figure out how to do it in a secure way. Maybe a combination of getting the app signature, plus time-based hashes, plus app-generated key pairs and the good old security though obscurity?
I'm looking for something as fail proof as possible. The reason why is because I need to deliver data to the app based on data gathered by the phone sensors, and if people can pose as my own app and send data to my api that wasn't processed by my own algorithms, it defeats its purpose.
I'm open to any effective solution, no matter how complicated. Tin foil hat solutions are greatly appreciated.
Any credentials that are stored in the app can be exposed by the user. In the case of Android, they can completely decompile your app and easily retrieve them.
If the connection to the server does not utilize SSL, they can be easily sniffed off the network.
Seriously, anybody who wants the credentials will get them, so don't worry about concealing them. In essence, you have a public API.
There are some pitfalls and it takes extra time to manage a public API.
Many public APIs still track by IP address and implement tarpits to simply slow down requests from any IP address that seems to be abusing the system. This way, legitimate users from the same IP address can still carry on, albeit slower.
You have to be willing to shut off an IP address or IP address range despite the fact that you may be blocking innocent and upstanding users at the same time as the abusers. If your application is free, it may give you more freedom since there is no expected level of service and no contract, but you may want to guard yourself with a legal agreement.
In general, if your service is popular enough that someone wants to attack it, that's usually a good sign, so don't worry about it too much early on, but do stay ahead of it. You don't want the reason for your app's failure to be because users got tired of waiting on a slow server.
Your other option is to have the users register, so you can block by credentials rather than IP address when you spot abuse.
Yes, It's public
This app will be distributed on Google Play and the Apple App Store so it should be implied that someone will have access to its binary and try to reverse engineer it.
From the moment its on the stores it's public, therefore anything sensitive on the app binary must be considered as potentially compromised.
The Difference Between WHO and WHAT is Accessing the API Server
Before I dive into your problem I would like to first clear a misconception about who and what is accessing an API server. I wrote a series of articles around API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you can read in detail the difference between who and what is accessing your API server, but I will extract here the main takes from it:
The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
Think about the who as the user your API server will be able to Authenticate and Authorize access to the data, and think about the what as the software making that request in behalf of the user.
So if you are not using user authentication in the app, then you are left with trying to attest what is doing the request.
Mobile Apps should be as much dumb as possible
The reason why is because I need to deliver data to the app based on data gathered by the phone sensors, and if people can pose as my own app and send data to my api that wasn't processed by my own algorithms, it defeats its purpose.
It sounds to me that you are saying that you have algorithms running on the phone to process data from the device sensors and then send them to the API server. If so then you should reconsider this approach and instead just collect the sensor values and send them to the API server and have it running the algorithm.
As I said anything inside your app binary is public, because as yourself said, it can be reverse engineered:
should be implied that someone will have access to its binary and try to reverse engineer it.
Keeping the algorithms in the backend will allow you to not reveal your business logic, and at same time you may reject requests with sensor readings that do not make sense(if is possible to do). This also brings you the benefit of not having to release a new version of the app each time you tweak the algorithm or fix a bug in it.
Runtime attacks
I was thinking something involving the app signatures, since every published app must be signed somehow, but I can't figure out how to do it in a secure way.
Anything you do at runtime to protect the request you are about to send to your API can be reverse engineered with tools like Frida:
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
Your Suggested Solutions
Security is all about layers of defense, thus you should add as many as you can afford and required by law(e.g GDPR in Europe), therefore any of your purposed solutions are one more layer the attacker needs to bypass, and depending on is skill-set and time is willing to spent on your mobile app it may prevent them to go any further, but in the end all of them can be bypassed.
Maybe a combination of getting the app signature, plus time-based hashes, plus app-generated key pairs and the good old security though obscurity?
Even when you use key pairs stored in the hardware trusted execution environment, all an attacker needs to do is to use an instrumentation framework to hook in the function of your code that uses the keys in order to extract or manipulate the parameters and return values of the function.
Android Hardware-backed Keystore
The availability of a trusted execution environment in a system on a chip (SoC) offers an opportunity for Android devices to provide hardware-backed, strong security services to the Android OS, to platform services, and even to third-party apps.
While it can be defeated I still recommend you to use it, because not all hackers have the skill set or are willing to spend the time on it, and I would recommend you to read this series of articles about Mobile API Security Techniques to learn about some complementary/similar techniques to the ones you described. This articles will teach you how API Keys, User Access Tokens, HMAC and TLS Pinning can be used to protect the API and how they can be bypassed.
Possible Better Solutions
Nowadays I see developers using Android SafetyNet to attest what is doing the request to the API server, but they fail to understand it's not intended to attest that the mobile app is what is doing the request, instead it's intended to attest the integrity of the device, and I go in more detail on my answer to the question Android equivalent of ios devicecheck. So should I use it? Yes you should, because it is one more layer of defense, that in this case tells you that your mobile app is not installed in a rooted device, unless SafetyNet has been bypassed.
Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary?
You can allow the API server to have an high degree of confidence that is indeed accepting requests only from your genuine app binary by implementing the Mobile App Attestation concept, and I describe it in more detail on this answer I gave to the question How to secure an API REST for mobile app?, specially the sections Securing the API Server and A Possible Better Solution.
Do you want to go the Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For APIS
OWASP API Security Top 10
The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
No. You're publishing a service with a public interface and your app will presumably only communicate via this REST API. Anything that your app can send, anyone else can send also. This means that the only way to secure access would be to authenticate in some way, i.e. keep a secret. However, you are also publishing your apps. This means that any secret in your app is essentially being given out also. You can't have it both ways; you can't expect to both give out your secret and keep it secret.
Though this is an old post, I thought I should share the updates from Google in this regard.
You can actually ensure that your Android application is calling the API using the SafetyNet mobile attestation APIs. This adds a little overhead on the network calls and prevents your application from running in a rooted device.
I found nothing similar like SafetyNet for iOS. Hence in my case, I checked the device configuration first in my login API and took different measures for Android and iOS. In case of iOS, I decided to keep a shared secret key between the server and the application. As the iOS applications are a little bit difficult to reversed engineered, I think this extra key checking adds some protection.
Of course, in both cases, you need to communicate over HTTPS.
As the other answers and comments imply, you cant truly restrict API access to only your app but you can take different measures to reduce the attempts. I believe the best solution is to make requests to your API (from native code of course) with a custom header like "App-Version-Key" (this key will be decided at compile time) and make your server check for this key to decide if it should accept or reject. Also when using this method you SHOULD use HTTPS/SSL as this will reduce the risk of people seeing your key by viewing the request on the network.
Regarding Cordova/Phonegap apps, I will be creating a plugin to do the above mentioned method. I will update this comment when its complete.
there is nothing much you can do. cause when you let some one in they can call your APIs. the most you can do is as below:
since you want only and only your application (with a specific package name and signature) calls your APIs, you can get the signature key of your apk pragmatically and send is to sever in every API call and if thats ok you response to the request. (or you can have a token API that your app calls it every beginning of the app and then use that token for other APIs - though token must be invalidated after some hours of not working with)
then you need to proguard your code so no one sees what you are sending and how you encrypt them. if you do a good encrypt decompiling will be so hard to do.
even signature of apk can be mocked in some hard ways but its the best you can do.
Someone have looked at Firebase App Check ?
https://firebase.google.com/docs/app-check
Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary?
I'm not sure if there is an absolute solution.
But, you can reduce unwanted requests.
Use an App Check:
The "Firebase App Check" can be used cross-platform (https://firebase.google.com/docs/app-check) - credit to #Xande-Rasta-Moura
iOS: https://developer.apple.com/documentation/devicecheck
Android: https://android-developers.googleblog.com/2013/01/verifying-back-end-calls-from-android.html
Use BasicAuth (for API requests)
Allow a user-agent header for mobile devices only (for API requests)
Use a robots.txt file to reduce bots
User-agent: *
Disallow: /
I am writing a desktop app using PyQt5 which uses the Wordnik API to get word definitions. I do not have server-side access, nor do I wish to invest in acquiring it. Is there any way I can reliably hide my key so I can share my program on GitHub?
At the very least you could store your API key in a separate source file (which you would exclude from the repository via .gitignore) and check for exceptions while importing that file (see this), alerting to provide own API key if that fails.
Storing the API key in a non-source configuration file is another option, but then your worries are in storing that file in a way that is not accessible to the end user of your application.
Unfortunately, no, our Wordnik terms of service don't allow for sharing keys where they are accessible by end-users. If your app is noncommercial you can share instructions for users to help them apply for and add their own Wordnik keys to their copy of the application (and this also helps you, in that your key won't hit our API limits based on your users).
If this is a commercial application, please get in touch with us (apiteam#wordnik) with more details about your use case as we are looking into how to make this easier. As a small nonprofit with limited engineering resources we can't promise a quick solution but since our mission is to find & share every English word we're always interested in learning more about how folks are using our API. :)
Thanks for using Wordnik!
I'm doing a hobby project Windows 8 app in WinJS. As I'm calling an external api, which requires an api key and oauth authentication, I've got a number of keys that I need to keep "secret".
I've seen places around the web with detailed descriptions on how to get access to and also modify the source code for WinJs (and C#) apps on your computer. But I think those were in the beta/preview time frame?
My Google skills don't seem to be able to tell me if this has been fixed since, does anyone know?
If it wasn't fixed, how do people handle these situations?
Any tips and suggestions welcome :)
You have a couple options here.
Integrate Azure Mobile Services and have it do the oAuth if possible. Your keys remain secret in the cloud.
Store the main key encrypted in your WinJs application. The secret then is also encrypted and stored locally. I use https://github.com/cauld/winjs-oauth-for-twitter and have a slight revision that when I get the key back I store it in the credential manager.
Any local application compiled from any computer language can be tampered with, all you need is a debugger. If you encrypt everything I in theory can just load up a debugger, attach to the http stack library and watch the data go out (excluding even easier techniques like Fiddler to watch this data) and extract whatever I want - fairly easily. So the question is what are you trying to prevent?
If your app could be facilitated to launch a man-in-the-middle attack, you should not keep confidential data in plain form for a long time, in memory or on disk. Also, storing encrypted data locally, alongside with the algorithm and the algorithm key/hash is a recipe for security incidents.
There is no silver bullet to protect your code or data from probing by the end user (or someone who has physical access to the end user's machine), see the amount of game save editors and game trainers out there. Don't put your business logic or important data (e.g. in-app purchases) in plain text or similar, at least add some obfuscation
Here is my requirements:
Usable by any mobile application I'm developing
I'm developing the mobile application, therefore I can implement any securing strategies.
Cacheable using classical HTTP Cache strategy
I'm using Varnish with a very basic configuration and it works well
Not publicly available
I don't want people be able to consume my API
Solutions I think of:
Use HTTPS, but it doesn't cover the last requirements because proxying request from the application will show the API KEY used.
Is there any possibility to do this? Using something like a private/public key for example?
Which fits well with HTTP, Apache, and Varnish.
There is no way to ensure that the other end of a network link is your application. This is not a solvable problem. You can obfuscate things with certificates, keys, secrets, whatever. But all of these can be reverse-engineered by the end user because they have access to the application. It's ok to use a little obfuscation like certificates or the like, but it cannot be made secure. Your server must assume that anyone connecting to it is hostile, and behave accordingly.
It is possible to authenticate users, since they can have accounts. So you can certainly ensure that only valid users may use your service. But you cannot ensure that they only use your application. If your current architecture requires that, you must redesign. It is not solvable, and most certainly not solvable on common mobile platforms.
If you can integrate a piece of secure hardware, such as a smartcard, then it is possible to improve security in that you can be more certain that the human at the other end is actually a customer, but even that does not guarantee that your application is the one connecting to the server, only that the smartcard is available to the application that is connecting.
For more on this subject, see Secure https encryption for iPhone app to webpage.
Even though it's true there's basically no way to guarantee your API is only consumed by your clients unless you use a Hardware secure element to store the secret (which would imply you making your own phone from scratch, any external device could be used by any non official client App as well) there are some fairly effective things you can do to obscure the API. To begin with, use HTTPS, that's a given. But the key here, is to do certificate pinning in your app. Certificate pining is a technique in which you store the valid public key certificate for the HTTPS server you are trying to connect. Then on every connection, you validate that it's an HTTPS connection (don't accept downgrade attacks), and more importantly, validate that it's exactly the same certificate. This way you prevent a network device in your path to perform a man in the middle attack, thus ensuring no one is listening in in your conversation with the server. By doing this, and being a bit clever about the way you store the API's parameters general design in your application (see code obfuscation, particularly how to obfuscate string constants), you can be fairly sure you are the only one talking to your server. Of course, security is only a function of how badly does someone want to break in your stuff. Doing this doesn't prevent a experienced reverse-engineer with time to spare to try (and possibly succeed) to decompile your source code and find what it is looking for. But doing all of this will force it to look at the binary, which is a couple of orders of magnitude more difficult to do than just performing a man in the middle attack. This is famously related to the latest snap chat flurrry of leaked images. Third party clients for snapchat exist, and they were created by reverse engineering the API, by means of a sniffer looking at the traffic during a man in the middle attack. If the snapchat app developers would have been smarter, they would've pinned their certificate into their app, absolutely guaranteeing it's snapchat's server who they're talking to, and the hackers would need to inspect the binary, a much more laborious task that perhaps given the effort involved, would not have been performed.
We use HTTPS and assign authorized users a key which is sent in and validated with each request.
We also use HMAC hashing.
Good read on this HMAC:
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
If I had let's say a sensitive report in PDF format and wanted to send it to someone, what is the most secure way?
Does a desktop application make it more secure? Since we are basically doing a client to server communication via private IP address? Then add some kind of standard encryption algorithm to the data as you send it over the wire?
What about a web based solution? In web based, you have a third person in the loop. Sure, it would do the same kind of encryption that I would have on a desktop.. but now instead of client->server directly, you have client->server | server<- client... You also have exposure to the broad internet for any intruders to jump in, making yourself more open to man-in-middle attack... One thing the web has going for it is digitial certificates but I think that is more authentication than authorization.. which the desktop problem doesnt have?
Obviously from a usability point of view - a person wants to just goto a web page and download a report he's expecting. But most secure? Is desktop the answer? Or is it just too hard to do from a usability perspective?
OK there seems to be some confusion. I am a software engineer and am facing a problem where business users have some secure documents that they need to distribute - I am just wondering if using the web and SSL/CA is the standard solution to this, or maybe a desktop application could be the answer??
The method that comes to mind as being very easy (as in it has been done a lot and is proven) is just distributing via a web site that is secured with SSL. It's trivial to set up (doesn't matter if you're running Windows, *nix, etc) and is a familiar pattern to the user.
Setting up a thick client is likely more work because you have to do the encryption yourself (not difficult these days, but there is more to know in terms of following best practices). I don't think that you'll gain much (any?) security from having to maintain a significantly larger set of code.
Most secure would be print it, give it to a courier in a locked briefcase, and have the courier hand deliver it. I think that'd be going overboard, though :)
In real world terms, unless you're talking national security (in which case, see courier option above), or Trade Secrets Which Could Doom Your Company (again, see courier option above), having a well encrypted file downloaded from the web is secure enough. Use PGP encryption (or similar), and I recommend the Encrypt and Sign option, make the original website a secure one as well, and you're probably fine.
The other thing about a desktop application is: how is it getting the report? If it's not generating the report locally, it's really doing just as many steps as a web page: app requests report, report generated, server notifies client, client downloads.
A third option, though, is to use something other than the website to download the reports. For instance, you could allow the user to request the report through the web, but provide a secure FTP (SFTP or FTPS) site or AS2 (or AS3) connection for the actual download.
Using a secure file transfer (or managed file transfer) is definitely the best option for securely transferring electronic data. There are smaller, more personal-use solutions out there like Dropbox or Enterprise solutions like BiscomDeliveryServer.com
Print it off, seal it in an envelope, hire some armed guards for protection and hand deliver it to them.
You may think its a silly answer, but unless you can identify what your threat vectors are any answer is pretty meaningless, since there is no guarantee it will address those threats.
Any system is only as secure as it's weakest link. If you sent the document securely and the user downloaded / saved it to their desktop then you'd be no better off than an unsecure system. Even worse they could get the docuemnt and then send it onto loads of people that shouldn't see it, etc. That leads on to a question whether you have an actual requirement that they can only view and not download the document? If not, why go to all this effort?
But if they are able to down load it, then the most secure method may be to send them an email telling them that the document is available. They then connect to a system (web / ftp?) using credentials sent separately to authenticate their access.
I'm surprised no one has mentioned a PK-encryption over email solution. Everyone in the "enterprise" gets a copy of everyone else's public key and their own private key. Lots of tools exist to do the heavy-lifting. Start with PGP and work from there.