I'm thinking about making a time limited full version of my App, so users can try it for example 7 days.
Is there a recommended Obj-C library?
First of all do not store your data inside the app. Otherwise it would be simple to delete the App from the filesystem and download it again restarting the countdown. Store it in User preferences or Application Support instead. You could use a plist for this. You could also use a hidden file if you like. Just don't make it too complicated or too invasive. Your app can be cracked no matter what security measures you use in the end. Just be fair enough to the end user that could be a prospective customer.
Here is a very nice link on the topic of implementing a time-limited trial in Cocoa:
http://lipidity.com/apple/shareware-licensing-techniques/
Without possibility to protect your data from manipulation/deletion it is not possible to do.
How do yo check, if it is first start of your application, if all your data is wiped out.
Some alternative is "hardcoded" id token and connection to the rest of world (at least for first start, to grab any kind signed data key)
Maybe you could use a server where store UUID's and first time they launched the App. Then, Each time they open your application, it asks your server if they can use it or not. It's harder than store dates on device but if you do that, users will access your application simply changing the date of the device on Settings.
Related
advertisingIdentifier is different for apps from the same vendor.
Of course there is an ability to add apps into group and share some "unique string". But I suppose that there must be some easier way.
I also read about "Uniquely Identifying a Macintosh Computer" but I suppose that such apps are rejected in mac AppStore.
In our app we access the system serial number. We use it to try prevent multiple users using the same account + for debug purposes (so not for ads or anything, our app has none).
We also have code to access the hardware uuid but that code isn't actually used at the moment, but it is in there, so not sure how deep Apple checks. So you might be able to use this one too. As an additional step you could hash either of these (or hash them appended or something).
This app has been on the AppStore for a long while now, and was never rejected for this reason. So I'd say accessing this data on macOS should be ok (for now) depending on usage and safe to submit to the app store.
Keep in mind that in some rare cases, the serial number will not be available. In that case we store a random string in UserDefaults.standard and use that cached value in the future.
Since this information won't be available to your 'other' app(s), this workaround won't work for you though.
Building a simple application which restricts usage based on the date. For example, you can only view a page 3 times per day.
However, if I use the device time, users can change their time and then view these pages again.
Is there another best practice method of doing so? Trying to avoid a call to the server. Using react-native. Thanks
Best practice is only use server time.
you can use following lib
https://github.com/artem-russkikh/react-native-clock-sync
This is kinda tricky without hitting the server.
into
Let's assume that the first time they open your app the user date is correct. (I really don't know any other way checking that in an offline way)
That moment we need to save the current timestamp to the localstorage (called AsyncStorafe in RN).
solution
The only way you can really be sure that the timestamp is correct is keep a task that counts every seconds/minute/hours, whatever is logical in your situation.
issue
Doing this in react native won't get you that far, but we are able to make a Java background service for example that we start as soon as the app closes. Here you should keep up with the time and save this when the app launches to a place where it's also accessible from react native (not sure if AsyncStorage is).
Info
Here you can find some information about bavkground tasks in RN: https://hackernoon.com/easy-os-background-tasks-in-react-native-bc4476c48b8a?source=linkShare-cdf0b7d5ccb4-1538965801
The most secure amd easy way of time cheat prevention is by hitting the server vut if that's not a possibility that this may be a interesting way to still check it. Good luck!
Im using basic auth in nginx, no issue there, but i would like to limit the number of distinct locations a user is authenticated,
The end goal is to prevent user sharing access data to website, since the website does real time "monitoring" of some data, i wan't that if the same user/pass combination is used from another ip, that or either both users stop getting data,
or one of them stops getting data.
I don't think that is a good idea, because a user may log in via pc and mobile phone at the same time and has two different ip addresses that way. Also http-auth isn't designed to do what you want it to. It would have to remember the ip-address and make it expire somehow, when the user leaves without logging out. Altogether would it be difficult to guess for how long the session is valid. Another problem is, that most users don't have static IPs and get disconnected by their providers every 24 hours. What happens if that occurs after a valid login?
The most popular method to deal with this kind of problems are session-cookies. These can be described as a one time password and you can use that for as long as you want or until it expires. SessionIDs are usually saved in some kind of database and making those sessions unique would not be a big deal and may therefor be what you want. Luckily the
ngx_http_auth_request_module would allow you to only implement this missing part and would bring you as close as you can get without developing your own nginx-module (see https://www.nginx.com/resources/wiki/modules/ for available modules).
On the other hand: Don't do that. Seriously. If you care for security, do not try to reinvent the wheel and use something, that has already proven. E.g. ngx_http_auth_jwt_module allows you the use of OpenID, which also sets you free from saving sensible user data on your server (because nobody wants to save passwords unless it is absolutely necessary).
Both of these methods require nginx-modules, which may not be installed on your server. If you don't have the permissions to build them, I would suggest to add that to your question, so that others can suggest solutions for non root servers.
If you want to keep it simpler you should also consider to generate download links each and every time and save ip-address and download link address in a database. Delete entries when a user downloads that file and you are done. For that to work you can use the
Content-Disposition: attachment; filename=FILENAME-HTTP-Header, so that your download.php doesn't save a file that called alike.
May be you can also find some kind of javascript to replace ngx_http_auth_jwt_module and use OpenID with http-auth. That can work, because it is possible to do the authentication with ajax as well.
Last but not least: If you still want to do http-auth, also use HTTPS, because your passwords won't be encrypted by this auth-method by default.
What you want to do is unusual so you will need to write a lot of the logic to handle the process.
Your code will need to store a User ID and IP Address pair for each loged in user and validate each attempted log in against this. As the previous answer pointed out, you will need to expire logins etc. Basically, you need to roll a session handler.
This is not impossible or particularly difficult but you need to write it yourself in one of the scripting languages available to Nginx which are either Perl, which is not recommended due to limited ecosystem in Nginx, or Lua, which is highly recommended due to the massive Nginx lua ecosystem (used by Cloudflare for instance).
You will need to compile in the 3rd party Nginx Lua Module and associated modules or just uninstall Nginx and use the Openresty Bundle which already has everything you will need included instead ... including Redis for storage if you need to scale up.
Here are some tools you can use as your building blocks
Openresty Session Library
Openresty Redis Session Library
Openresty Encrypted Session Module
Note that you can implement Openresty stuff directly in Nginx if you wish without having to run Openresty as it is just a convenient bundle of Nginx and useful module.
We intend to sell our framework on the net ,and it needs to be protected in a matter than if someone buying it, he can't put it on the net, or give it to other developers .
We dont want to find it all over the net after a few months.
I had a few ways in mind but each had its catch .
Give a unique ID to every developer, and program that id to the framework, so he must enter that to use it. problem is ,that he can give the framework with the id to anyone .
Ask for the device number and enable only that device in my framework for each developer. problem here is that when he put it on store, all users cant use that since they have others device id.
Use the net to check some how(??) which i preferred not to limit the users to that need.
I can program each framework with a code, that only me can extract, so when i find it on the net i can be sure what dev put it in there (it doesn't help-i cant sue everyone)
Is there any other way to make the framework per developer but also let it work on all other users at the appstore when its there ?
Thanks .
#diederikh makes very good points, and NicolasMiari also provides good insight. The best answer IMO is a combination of these two. (While keeping in mind diederikh's excellent advice that your goal is to come up with something simple that will make things hard on legitimate customers.)
Rather than recompiling your entire framework for every customer, you make your license key depend on their bundle identifier. They send you their bundle ID. You use your private key and sign their bundle id. This provides you a hash that you send to them. Now, at runtime, your framework uses the public key (which is not sensitive; you could publish it anywhere) to verify your signature. See SecKeyRawVerify() for doing that on iOS.
You can use this approach to create time-limited keys. Just include time stamps in the signed data.
Using this approach, you could, if you wanted, let customers test your framework indefinitely by using your bundle identifier. You would make a signed hash of that identifier available to trial customers. But as soon as they want to upload to AppStore, they would have to change the identifier and pay you for a new signed key.
There certainly is a way to get around this. Attackers could modify your framework to ignore the signature verification. But that's always true, and preventing that is better done with lawyers after the fact than with DRM that will only likely cause trouble for paying customers.
Look at how PSPDFKit does it. If you want to use it out of demo mode you'll have to call a method with an unique ID. This ID will enable functionality which is not available in demo mode.
You can also sign (with the codesign tool) the framework with an unique certificate for each customer.
I would not worry too much; if will always find a way around your locks.
We are creating an app as follows:
User starts with 2 free "tokens"
User can buy a pack of 10 tokens with $.99 in-app purchase
We have implemented this using NSUserDefaults to save the number of tokens.
Is there a way to make our free 2 token setting persistent? Even if they delete the app? Right now you can delete the app and reinstall to get 2 tokens again. iOS 5 has NSUbiquitousKeyValueStore for saving settings to iCloud, is that any better?
If not we will have to use a web service for this...
NOTE: This app is in MonoTouch, but probably irrelevant to the question. Also, in our app, the user wouldn't care to reinstall the app to get 2 more tokens (there is no other settings or game progress they would lose).
Just my 2c as #Almo covers most of this already and should get the credits :-)
NSUbiquitousKeyValueStore has the advantage of being by-user, e.g. several devices would share the same free tokens. OTOH that might not be something you want in your app...
Leaving data after uninstallation goes against the sandboxing of applications. There are ways to do it, like you can add images/photos/contacts/..., but unlikely to be "Apple approved" and more than likely easy to hack around.
So I also suggest you to use a web service. A simple way would be to validate with the service (e.g. using the device's MAC address since the device unique identifier is going away) when no application data is found (install and re-install) if it's a know device (no token) or not (get tokens).
If the paid tokens are re-usable (could be re-played by re-installing a backup that includes them as data) then you might want to track them with the web service. Non-reusable tokens won't suffer from this (and are likely easier to deal with).
You can set token to the Keychain. If the user uninstall app and install it again you can restore token from the Keychain.
sskeychain
Even if you try to make the setting persistent, I don't think it would be that hard for them to find that and delete it as well during a reinstall. If you want to prevent just casual cheating, maybe that's fine. But if this is your revenue stream, I'd recommend using a webservice.
Edited to add: I don't have any experience with iCloud. That might make sense, too.