This topic is the discussion of many, many forum threads and email list discussions. Not necessarily here at macscripter, but certainly elsewhere. Ultimately, this is a “roll your own” subject, meaning that you have to tailor the methods you use to exactly what your own unique needs are. You need to clearly define what your trial period means. Do you want the app to irrevocably stop working after the period ends, or do you just want to pop up reminders? Do features get enabled/disabled based on registration? How far do you want to go to make sure you can’t just reinstall to reset the trial period? How do users register… via email, internet, other? There are many concerns, and once you start looking into it you may find yourself changing your approach to either your registration scheme, or to your entire app itself.
It’s not necessarily bad to store your reg info in user defaults, but what you need to accommodate is the likelihood that most users will try to scrap their prefs first to try to get around your registration. As Kevin said, another approach is to use a plist or file within the bundle to record user registrations. This, too, can be circumvented by simply uninstalling and reinstalling. The third method is to use an arbitrary location for recording a registration. Using this approach gets complicated, though. While your instinct would be to bury the file really deep in a filesystem hole somewhere, you need to be careful with trying to hide it too far away. Remember that some users don’t have the broad read/write authority you probably do. Consider using invisible files to store your data, and pick a home that all users will have installed on their machine and that each user will have write access to. A good approach will likely have a combination of multiple methods of authentication, all working together to give you whatever level of security you’re after.
Another very important matter is obfuscation… both in your code and in your files. Obviously, if you have a key like “RegistrationNumber” in your plist file, it’s a beacon for user tampering… and ultimately fraudulent use of your software. In fact, do put a “RegistrationNumber” key in your plist, but NEVER use it for anything related to your registration scheme. Write arbitrarily to it parallel to your actual registration tasks as a dummy key so people get frustrated trying to figure it out. If you’re going to write things to disk that the user can readily get at (which you should assume is EVERYTHING) then try to name things and store information in a way that the user is less likely to understand without significant investment of time. Name the key that stores your registration number something like “WindowFrame” or “lastOpenPanelFilePath”. Don’t store unaltered, plain text in your plist values. At least save them as data objects, or add encryption methods to your code so you can encrypt the text before writing it to file. The same rules generally should apply to any data you write to your other bundle/hidden files. In your bundle file, keep a list of all users that have launched the app, what their registration status is, and an encrypted record of their registration key if they have one. If you keep a hidden file somewhere else, just make a copy of the bundle file. That way you can compare the two files as another validation method, and you can compare their contents with the reg data that the user is trying to validate when they’re using your software. It’s wise, too, to always write SOMETHING to file. Even if the user hasn’t registered, still write a placeholder to file where their key would be stored. This makes it more difficult to simply look at a before/after version of your files to find where the reg info is stored. If used with good, creative encryption, you can make it extremely difficult for someone to crack your scheme.
As far as hiding things in your code goes, pretty much the same rules apply here too. Don’t make routines in your code named “DecryptPassword” or “validateRegistration”. Anyone who happens to get a hold of your code could easily find and possibly exploit your reg scheme. Use dummy names for this to make it much harder for people to pry into your code. Also, make sure that your code is being compiled before you distribute it. In applescript studio apps, when you build them as ‘release’ versions, they should be compiled as read-only. There are certain cases where they are not though, so go into the bundle and try to open your scripts in script builder to make sure that they’re not plain text versions of your code. OUCH! Bye-bye registration scheme! If you find a case where your code is not being compiled (such as when building bundles like applescript-based plugins) you can add a build phase that executes a script to do that for you while your app is being built.
I would start by determining what level of security you want your registration scheme to have. If you just want to steer the user towards registration of your app, then you can usually get away with simply nagging them for registration. Writing nagging into an app is really easy and fairly bulletproof. Just set an encrypted key in your plist that determines whether the user is registered or not and pop up a nag window until they do. Beyond this, the level of complication grows. If you want a relatively bombproof, all-inclusive demo period that results in near complete inability to continue use or reinstall, you’ll have to go to great lengths to make this happen. Big development companies that do this successfully have whole teams of people who handle only registration management. Thinking that you’re going to do the same, while possible, is probably not reasonable. Just try to come up with something that protects your asset in a reasonable way, knowing as you go into it that you WILL NOT keep someone from pirating your software if they want to badly enough.
While the user is entitled to do whatever they want with their computer, unless you’re writing free/opensource software, your software still belongs to you. The terms of your license should reflect that you require registration and that trying to get around the registration will terminate their license to use it. Remember, too, though, that they don’t care. People will definitely try to get around paying you for your work, so you must try to make it very difficult for them to do that… to the point that simply paying for it is easier than hacking it. Just don’t make it easy for someone to get around your scheme, and you will knock off most of the users who wouldn’t have payed for it anyways. Try to test out your scheme really well before throwing it at users, though, because you also want to make sure that honest, registered users have no obstacles to their use of your product.