Can apps keep secrets? - android

A given server API should be publicly accessible to all unauthorized users, but requests should only be allowed to originate from one specific app.
This should, in theory, be accomplished by having the app HMAC-sign all API requests, and by having the server correctly issue and store nonces (to avoid replay attacks).
Question::
Are there any known methods for a mobile app to slice, dice, chop and XOR a secret, in a way that makes it extremely hard, if not impossible, for hackers and crackers to retrieve the key?

Create a free in-app purchase with iTunes connect and have users "buy" it (even though they won't be charged anything)... then verify the receipt with your servers... Apple will provide a transaction receipt which will verify that it originated from your app.
https://developer.apple.com/library/ios/#releasenotes/StoreKit/IAP_ReceiptValidation/

Related

secure verification process between android app and server

I am writing an android application which will not be available by the google play store. I am looking into how can I accomplish to verify that any user of the application is indeed a verified user.
I would like to use a server for this process that the application is using anyway to send/receive data. My idea was setting up something like a challenge that only verified clients would be able to pass. So anyone using a fake app will not be able to bypass this.
Is there any standard approach to this problem? I have searched a bit but did not find something covering this entirely. Please keep in mind that I am aware of the fact that given the fact the application runs on an android phone which is a device out of my reach there will probably always be ways to bypass the challenges. I am looking to see what the majority is doing in these cases.
There are two probable issues here. First is user authentication (authn) and authorization (authz), and the second is verifying that the client app itself is authentic.
For user authn/authz, I would use some form of OAuth2 with OpenID/Connect. The end result is that you are authorizing your client app to access your end resources on behalf of the user. There are open source and free commercial services available to get you started.
More problematic is authentication of the app itself. API keys are the standard approach here, but these are static secrets which don't do much good if the app is tampered with or the key is observed in the communications channel. No matter how hard you try to hide or compute the secret as needed, if your endpoint is valuable enough, someone will do the work necessary to extract and abuse the secret and then your backend.
You are on a good track thinking about some form of challenge-response protocol. Captchas are the canonical approach here, but they are quite annoying to users on a mobile app and are not always very effective. I believe (and full disclosure, so does my company) that attesting the app's authenticity through a cryptographically secure challenge is a solid strategy. The attestation service challenges the app and analyzes its response. The challenge evaluates whether the app's code has been tampered with and assesses the state of the runtime (is app rooted? running in a debugger? frameworks like frida or xposed present? etc.). The app is issued a short-lifetime token - properly signed if the attestation passes, invalid otherwise. There's no secret in the app, and the app does not make the authentication decision; it just passes on the token to your backend which checks the token lifetime and signature to determine the app authenticity. No token or invalid token and you know this is a bot or tampered app.
For background on user and app authenticity, check out a 3 part blog post, starting with Mobile API Security Techniques, or if you prefer video, check out A Tour of Mobile API Underprotection. I encourage you to also check out approov.io for how this can be implemented as a service.

Android In-App Purchases, protection from piracy

I have read Can In-App Purchase Prevent Software Piracy recently.
It's talking about using ssl etc. for protecting apps from piracy.
I'm planning to do something different, but i'm not sure if it's enough.
User gonna sign up for my services in app, and then when user wants to activate some paid stuff.
User will pay for it and when the purchase completed,the app will write onto sql database about activating something.
And when the app connected to internet,it's gonna get the data of whether something is activated or not,if something activated,it will enable it. My app works with internet, so most probably checking process will always work.
And i will send device properties onto server,so i won't allow user to use the application with same username and password more than 3 devices.
The Question is, is it enough? my server won't use ssl or something but sql database.
This is definitely more of a philosophical question. When it comes to security in general, there is never enough. It comes down to risk-assessment.
Your situation has three-facets:
Purchase authentication - which if you are doing it right, Google has created a practically secure solution. If you don't even call the server unless the purchase is authenticated then SSL will do nothing to help make this facet more secure.
Limiting devices - this is where you can benefit from SSL. The risk of not having SSL, is if you have someone smart enough to spoof your server and perform a Man-in-the-Middle attack. Which if that was to happen, they only gain the ability to access the content with more than the proposed 3 devices.
Content protection - if the content on the server is what the customer is paying to get access to, that can possibly be a target. Someone may try to spoof a device and access your server content. SSL may or may not help with this, depending on server-side implementation.
My two-cents*: You can spend days/weeks/months implementing a solution, or you can put a practical (less-secure) solution and focus more on your user experience. i.e. What is more important, total security or the number of users and their satisfaction?
*Unless your content needs protection because of contractual obligations.

Secure way to store sensitive information in Android

Does anyone knows what is the most secure way to store sensitive information in application? Because using internal storage and shared preferences is vulnerable if person who want that information have a rooted phone.
Case is that I have some kind of activation code which needs to be stored somewhere inside the phone (not on server) for further communication and authentication with server side, that code needs to be secured and not available to other apps and users, even on a rooted phone. Also, user can not be bothered with additional verification (he enters the PIN code when he enters the application and send that code to the server side for authentication) .
Bottom line, is there a secure way to store something and to be secure that it will remain hidden, even on a rooted phone?
Unfortunately the commenters are correct. There is no way to guarantee with 100% security that the activation code can't be hacked. Microsoft has spent millions of dollars on this, and there are still pirated copies of Windows out there, because at the end of the day you have no control of the code on the client. If you endow the client with the ability to decrypt or otherwise access this stored authentication code (without needing to go to the server), then someone can reverse engineer the app to undo your protection. This is true even if you retrieve a decrypt key from the server.
The best way to do this depends on your use case, but here are some ideas:
Have the client submit the "activation code" to the server, where you can blacklist it if you think it's stolen. This is how Windows works. This is the only option you have if you want to use an activation code and not bother the user.
Have the user register an account and have the app resubmit the user's credentials each time it runs. This way you have a user account to deactivate if you suspect piracy.
Have the server provide the decrypt key. This does not guarantee that the activation code stays safe, but it does up the bar for potential reverse engineers.
Drop the whole DRM idea completely, and focus your attention on making a good product. Studies that music companies have shown that dropping the DRM makes no difference in the number of people who buy your product.

How to securely verify a user's subscription to an Android app?

I know very little about security or servers, but am making an Android app that allows users to purchase an in-app subscription. As recommended, I want to use the Google Play Developer API and store the necessary data on my own server. However, I can't think of a way to do this without having a line in my code like
if(userIsSubscribed){
//give access to purchased data
}
A hacker could obviously go in and just flip that to if(true). What should I do instead?
Obfuscate your app code as a minimum. Also do the subscription check on the server, before you send the content. That is one of the reasons they have an Web API.
Basically, anything the user (and potential cracker) has access to (i.e., your app) cannot be trusted. Things they don't have direct access to (i.e., your content server) can be trusted a bit more and it is a good idea to move all sensitive operations and/or data there, where possible.

How can I manage in-app billing transactions on an external server securely?

I'm attempting to implement a system for upgrading/unlocking various features of my app using "managed" purchases with in-app billing, and I'm getting bogged down by the lack of in-depth documentation or examples.
My app's purpose is to retrieve/parse and display data from my own server, and the documentation on http://developer.android.com/guide/market/billing/billing_best_practices.html states:
If you are using a remote server to deliver or manage content, have your application verify the purchase state of the unlocked content whenever a user accesses the content.
My question is, what is the best way to go about this in terms of actual workflow?
As far as I can tell, on successful purchase I would store the purchase information on my server as well as locally in the app. When the app runs, I would send the order ID to my server and the server would check to see if the order is valid (firstly checking that the order exists in my server's database, and secondly checking if I have not manually revoked the order for whatever reason).
If that is verified, the server would send a response to the app that the requested features are "licensed", and the app would provide the unlocked features/content to the user.
The obvious problems I can see with this are:
A rooted user could easily just alter the local app's SQLITE database (or whatever other method I use to store order information) to inject a valid order ID.
If network access is down, or my server is down, I still want the app to be able to run (with cached data) with all the user's purchased features.
Potential ways around the first problem that I can see involve sending some sort of device identifier with the verification request, and monitoring that at my server's end - revoking the order if a large number of devices are accessing the order in a short period of time.
For the second problem, I can't figure out an adequate solution. I initially thought that each time the verification is successful, the time this verification took place would be stored. Then, the app would continue to run with the unlocked features for say, 48 hours after the last successful verification. The issue with that is, how can I securely store this time value? Again, rooted users could simply alter the value and the app would be none-the-wiser.
Has anyone designed a server-based system for managing in-app billing purchases and can offer some suggestions?
Google Licensing provides a way to allow a cached 'You're license is valid' response to stay alive.
Application Licensing
You can also encrypt the data your are storing. If they have paid for it, they get to decrypt it. If no network access available, then implement a similar caching scheme as Application Licensing (currently licensed under the Apache License, Version 2.0).

Categories

Resources