Secure database and webpage against modification - database

My website provides extremely sensible information (think of bank account numbers) publicly available through webpages and webservices. The customers may modify these information when authentified with a username and a password.
Any hacking intrusion that would successfully modify the entries of the database, or modify the information displayed on the webpage, would be disastrous, as account numbers might then be incorrect and money could be directed to a malicious bank account.
Do you have any general advices about the architecture that would make such a service as robust as possible? I would not be responsible in case of a weak password, so my main concern is about attacks that would simply bypass the authentication process and modify the database without triggering any alert on my side; it could also be the html code of the webpage that is directly modified to show different information...
Thank you

In this case i would make sure to harden the system itself as good as possible. This includes a very broad spectrum reaching from Security Roles over transaction based usage of the database, logging as well as the prevention of all sorts of attacks like SQL injection, cross site scripting in general and maybe if its a that sensible system use certificates and general IP checks (like have a white list of IPs that are allowed to populate requests to the system that do not instantly get refused). Not to mention your Host architecture has to be protected regardless of the implemented security features inside your system (key words: firewalls, user privileges etc.). During the development process there should always be auto code checking software (like Sonar) running to detect logical errors and stuff.
Then it could also be a good idear to have a second system just to monitor your primary systems status. This system should log and notify you on:
changes made to the system itself (like if someone has access to your business logic and for examply removes authentication logic)
changes made to the database that are not consistent with your primary systems state.
detect suspicious actions: Banks for example have rules that apply on your account. Like if you used to make payments within europe for the last time and then out of nothing make a huge payment to lets say china you would recive a notification to commit this payment. The payment then would not be triggered unless that second commitment of the customer.
In the end you already pointed out correctly that you just can harden it as good as possible but generally not make it "100%" safe (at least in theory) so to have a good level of security part of the total system would include beeing able to detect unwanted changes, identify the exact changes already beeing made and have information on the overall status of your system to allow a rollback or manual correction of a corruptet state in case it already happened.
Even after having implemented mentioned techniques you would have to continously check for security bugs in used frameworks, librarys and the system as a full (like using security penetration frameworks that auto try to corrupt your system).
What i want to show you with my answer is what the comments already suggest: It is a very broad and complex topic with multiple layers of security concernes you will have to either study yourself or have framework solutions that "ensure" you to take care of the topic (like Webframeworks often include basic XSS prevention).

Without wanting to sound harsh, but if you have to ask this question on Stack Overflow, you're not really qualified to work on this project.
The financial value of your data sounds like it's enough for an attacker to expend significant resources breaching your defenses - and the consequences of such a breach would be disastrous for your organization and its customers; it could lead to the organization having to close down. You really don't want to be learning about security from strangers on the internet in this case.
One place to start learning in is with the established standards for managing financial information, often referred to as "PCI standards"; these provide guidelines for hardware, software and processes for organizations that deal with payment details.
There are numerous books on IT security; I like the "Hacking Exposed" series, and "Security Engineering".
You might also bring in specialized IT security consultants; I've worked with a number of these guys, and many of them are very good at helping you engineer security into your solution.

Related

Is splitting databases a legitimate security measure?

When previous devs at my company had to store sensitive user data (for example, medical records), they did the following. I doubt its merits.
There is data considered "insensitive" (user login, profile info), and "sensitive" (user medical records).
There are three databases. Insensitive data in A, medical records in B, and the mapping between A and B in C.
A hacker must hack all three databases to tie users (A) to medical records (B).
Our own backend code calls C to tie A and B data together for user display. I think the ubiquity of this code invalidates the benefit of splitting databases: if the hacker accesses our system, he can call our logic.
What benefits of the above system am I missing (or are there better ways to secure such data)?
I'd say that once your system has been compromised and the assailant is past the threshold with access, then the databases are just a matter of time. What it is doing is at least perhaps delaying to intruder in their intent - but the cost (in terms of maintenance, performance, project clarity and so on) might outweigh the benefits.
I'm sure there will be sufficient information for a determined person to decide that X, Y and Z databases are linked - unless you obfuscate database names, table names and other structural indicators.
Ideally you should be looking to make your system impenetrable, all other things beyond that are mitigations, the treating of symptoms with neglect for the problem (that you've been exploited), of which the trade-off must be considered uniquely to the situation.
In my experience and opinion, splitting the database like this is a strangely contrived approach to security that I find to be ingeniously silly.
In response to the general question "is splitting databases a legitimate security measure", isolation is indeed a well-known, useful tool for implementing security. Whether its benefits outweigh its drawbacks (generally, additional complexity) is very much situation-specific and I don't know the answer in your system's case.
Suppose for example that someone wanted to build an analytics application on top of your data. It would be very useful to have the mapping data completely out of the picture. If the analytics app is breached, the mapping information is not at risk.
Responding to some comments below, even in your system's specific case, it's not a foregone conclusion that "breaching the system" amounts to breaching all databases at once. Suppose that an attacker exploits a SQL injection vulnerability in your application. If the mapping data is separate and hardened (extra controls on code that accesses mappings, say), then isolation can be the difference between exposing unassociated data and associated data.
Not arguing that it is a good design for your system. Just trying to explain different kinds of rationale that can go into this.
I'm using the same isolation strategy in a similar situation. The "databases" in my case are configuration repositories. All of the preprod configuration goes in one repo and the production config goes in a separate repo. All developers have access to the preprod repo, but only release engineers have access to the prod repo. The rationale is that I want defense in depth: while I could certainly implement access controls on the individual repo folders, I'd rather make the production config simply network-unreachable to all unauthorized staff.
Yes, splitting data into separate stores can help security. As James Anderson writes, most database systems allow you to grant different privileges on individual tables.
However, most security analysis looks for the weakest link; I doubt whether your weakest link is the way your databases are split out. So, unless you've nailed down a whole bunch of other things - password management being an obvious one, SQL injection attacks another - at best, the database design is pointless; at worst, it is adding complexity to the application which causes bugs; most security vulnerabilities come from bugs.
It can also lead to a false sense of security - "we're covered on security, we split our databases", or a cavalier attitude to securing the "non-sensitive" data.
Oh, and if you decide that the user's login credentials are "not sensitive", you're basically giving an attacker the option of simply impersonating legitimate users of the system to steal your data once they have penetrated your "non-sensitive" data store.
On most serious DBMS systems you can control access at table (sometimes even row level).
So storing the sensitive data in separate tables is a valid way for restricting the access to the confidential data.
While nothing will protect you from a hacker who gets root (as other posters have pointed out). But this strategy will protect you from unauthorized users within your system gaining access, and, by extension from hackers who have obtained their userids and passwords. As spoofing low level employees into giving password details is still one of the commonest "attacks" this is well worth doing.
The big "if" is can you really split your users into "have access" and "have limited access" groups?

ASP.NET - What is the best way to block the application usage?

Our clients must pay a monthly Fee... if they don't, what is the best way to block the asp.net software usage?
Note: The application runs on the client own server, its not a SaaS app...
My ideas are:
Idea: Host a Web Service on the internet that the application will use to know if the client can use the software.
Issue 1 - What happen if the client internet fails? Or the data center fails?
Possible Answer: Make each web service access to send a key that is valid for 7 or 15 days, so each web service consult will enable the software to run more 7 or 15 days, this way the application will only be locked after 7 or 15 days without consulting our web service.
Issue 2 - And if the client don't have or don't want to enable internet access to the application?
Idea 2: Send a key monthly to the client.
Issue - How to make a offline key?
Possible Answer: Generate a Hash using the "limit" date, so each login try on software will compare the today hash with the key?
Issue 2 - Where to store the key?
Possible Answer: Database (not good, too easy to change), text file, registry, code file, assembly...
Any opinion will be very appreciated!
Ah, the age old issue of DRM. And that's what you're talking about here. Frankly, the fundamental answer to your question is: you can't. No matter what you do to the system, it can be hacked and modded in such a way that your DRM authentication scheme can be bypassed and/or broken.
This is a fundamental fact of software development: it can and will be pirated.
So, the answer to your question is that you will have to trust the client to pay you the fees you determine to be correct (which is the whole point of contracts in this situation).
Any other actions you take are a hardship and annoyance on your paying customer, and has the potential to erode your customer base.
Now, if you want control of your software in the nature described, then do not provide it to users to run on their own servers. Force them to be SaaS. In that way, you control all of that. But this is the only way.
Something that you don't appear to be thinking about, but I have seen networks which do not allow any type of "dial home" solutions, as a majority of the systems were internally focused and thus these internal servers were NOT allowed to contact the outer internet. At all. It was deemed a security risk to even allow them access. How would you handle those networks?
Frankly, if I was the customer, and I paid my fees to license your software (which I installed on my own device) I would be irate if I had to allow that device access to the internet in order for it to work. Doubly so, if the software in question was any type of financial management, customer management, HR management, quality management, inventory management, sales, or just anything related to my business, customers or employees. I don't trust software developers enough to have their software talk to something else when my business-relevant data is held in their software.
In the end, what you are describing is an antagonistic approach to take with your paying customers. If you don't believe me, look at the comments that UbiSoft is getting for their latest customer-hating DRM scheme.
IMO, you have two good paths here:
Go SaaS
Ensure your contract has a
bite for non-payment
usually you provide an scrambled key that includes a valid authorization token and the expiration date through which service is paid. Then the installer will use this to "activate" your software. Not sure how this would be viewed if you have 1-2 week periods. you'd want to warn them about upcoming expiration. Also not sure how to tell if they've set their own clock back.
In short, nothing will be perfect.
I've dealt with this before and its not possible to make a perfect system. There are risks in anything you do. The best thing is to weigh your options, and determine the method that has the least likelihood of being hacked and the most likelihood of working correctly and easily for the customer.
Like others have said, they could change their clock and invalidate the license checking mechanism. If you didn't trust the user, you could make the license system connect to your servers. You would then need to ensure that they always have a connection to your servers to check the license.
What if there is a valid reason that they cannot access your server?
Their internet connection has a problem.
YOUR internet connection has a problem.
In that case, should you disable the application? Probably not. But then again, what if they shut down the connection on purpose? Then you would WANT to disable the application.
If you give them a monthly key, you're adding a monthly annoyance and you may lose a customer after a while (people tend to do business with those who make it easy).
For example: If you base it on their clock, and the application needs their clock to be accurate for some reason, then its unlikely that the customer will change their clock.
I agree with Stephen but ultimately, I think that your contract is your best ally here.
As been previously mentioned, you don't want to inconvenience customers, especially if you have a large deployment.
As for SaaS, if I were a customer using your product and you said that the model is changing and we need to access the software from your server and ours must be decommissioned, I'd not be happy. I'd probably use the opportunity to switch packages.
In corporate settings, the contract really is the best way to handle these issues. I've worked on licensing issues for desktop and ASP.NET applications and they can cause a number of headaches for both you and your client.
However, if you insist on using something like this I suggest you go with a middle ground. Instead of only unlocking the application for a week or two, provide a license for 6 months or a year. This way, if you run into licensing issues (and you will run into issues) they only occur once a year rather than a couple of times per month. That will be cheaper for you in support and your clients will be less unhappy about dealing with licensing issues. If the company stops paying and you need to terminate the license you can handle that on a one-off basis, using contract enforcement as needed.
On the web service or client license options, I think a good license system would incorporate both. A client license to provide a the application a stable license and a web service to generate and deliver the license key when it is time for the application to be renewed. If the client won't allow the application to call home to get the license key also provide a manual entry method.
If you are going to store a license on the client, do not try to build a component yourself. There are many components available which will be much more robust and reliable than the one you build. There is a .NET .licx-based licensing method and a number of 3rd party methods that you can use. Which one is most appropriate depends on your scenario: how flexible you want the license and what other options you need. Most importantly, find something reliable - any time your customers spend fixing problems caused by licensing is non-productive for them and will reflect poorly on the application.
The important thing to keep in mind is that no system is fool proof. If your application is valuable, someone is going to figure out how to steal it. But at the corporate level and with custom software it's more likely the licensing will be used to remind people to pay rather than stop wholesale piracy.

Translucent Databases

I am building an application with health information inside. This application will be consumer-facing with is new for me. I would like a method to put privacy concerns completely at ease. As I review methods for securing sensitive data in publicly accessible databases I have frequently come across the notion of database translucency. There is the original book on the subject and an excellent tutorial on the subject from Oriellynet.
My concern is that I have seen very little information regarding this idea on what I would consider very-modern programming sites (like this one). There does not seem to be an article about the idea on wikipedia. No questions on the subject here, and no very recent tutorials or articles on the subject. To be uber-brief, the idea is that certain data is clear to some users of the system, while other users a cryptographically prevented from accessing that data, even if they have administrator access.
I have done substantial work on a prototype database that provides translucent data access. I have run across a considerable problem: To be truly translucent, there can be no mechanism for password recovery. If an administrator can reset a users password, then they can briefly gain access to a users data. To be truly translucent, the user must never loose the password.
Those of us who use strong encryption to protect private data in our daily lives (technorati to be sure) are used to this problem when using these kinds of strong encryption systems. If the word "blowfish" is part of your daily lexicon that is one thing, but a website that is consumer focused? I am concerned that users will not be willing to wrap their mind around the "truly encrypted just for you" notion implicit with true database translucency. I am afraid of the support call that begins with "I lost my password" and ends with me saying "There is nothing that I can do for you".
My question: Should I implement this method in my application? Are there other open source applications that have gone down this route that I can compare database designs with (esp using php/MySQL)? I anyone else pursuing these kind of truly secure, but really inconvenient feature sets? Is there another database security model that is more popular and modern that I have missed? Was database translucency a fad or a legitimate database design method that I should embrace? While I always appreciate discussion I would prefer objective answers that I can leverage in my design.
So, I've been looking at something similar to this recently, and hit upon the same issue. The solution I'm considering implementing is as follows:
Upon registration, create a unique, secure (long) key for the user and use this to encrypt their data.
Encrypt this key with the user's password using e.g. AES and store it in the database.
At this point, you're still in the situation where if the user forgets their password, they've had it.
Create a public/private key pair representing your organisation, and store the public key on the server.
Split the private portion of the key into several components and give each to people (e.g. directors of your company) who have a significant stake (preferably financial) in the continued success of your company. Do this such that any two, or any three people can get together and restore the full private key when required. Encrypt each person's key with their own password.
When a user registers, as well as encrypting their key with their password, encrypt it with the organisational public key and store it somewhere.
Create a password reset form which records a request to reset the password of a user, along with some proof that the user is who they say they are (e.g. challenge/response).
Record these reset requests (optionally encrypted using the public key again) in the database.
Once per hour/day/week/month, get the requisite key-holders together, and use their combined keys to process the accrued reset requests, decrypting the keys of users who successfully proved they are who they say they are.
There are lots of challenges and considerations in this. I've got a few thoughts on most of these, but would be interested in others opinions too:
How to split the key safely between multiple people so that no one person can decrypt the stored keys.
How to minimise the number of keys that would be exposed if the 'master keys' genuinely fell into the wrong hands.
How to make sure that if (heaven forbid) your key-holders lost their keys, then (a) there's no risk of exposure of the data, and (b) there's no risk that suddenly the ability to reset passwords is lost forever.
How to successfully validate that someone really is who they say they are without making this a glaring hole in your whole security approach.
Anything you implement in this area WILL reduce the security of the translucent database approach, without a doubt, but this may be a worthwhile compromise depending on the nature of your data.
Should I implement this method in my application?
Well like other things in life, there is a trade off :) It's probably more secure but harder to built.
Are there other open source applications that have gone down this route that I can compare database designs with (esp using php/MySQL)?
Don't know, I guess the tools are there to do it yourself :)
Is anyone else pursuing these kind of truly secure, but really inconvenient feature sets?
Yes, but it seems like it's still in an immature state, like your problem you describe concerning lost passwords.
Is there another database security model that is more popular and modern that I have missed?
Basically there are two kinds of database connections. One option gives users a real database account, the other is to use single sign-on to the database. Prior to the web coming along, there were proponents of both models in the client/server world, but amongst web developers the single sign-on method is leading.
Was database translucency a fad or a legitimate database design method that I should embrace?
Don't think so, the UNIX password database, for instance, is a great example of a basic translucent database ;)
here something to read link text
Re: translucent databases. You could, I suppose, use fingerprints. What about burn victims, or people who end up losing their fingerprints? Oops. Is it worth that small percentage of users?
Familiarize yourself with HIPAA, especially when it comes to technology.
Remember that no system is truly secure, except Skynet*, and look what happened with that! Humans are in charge. When you work in a medical company, you sign an NDA indicating that you won't release any of the information you learn as part of your duties because it is confidential.
There will be someone to reset people's passwords. That's the way it is, because not everyone is technologically competent, and that's the way it stays for now.
You only have to implement security as well as HIPAA says.
in truth, there is another truly secure system: it is unplugged from both the network and the electricity, and it is turned off.
Slightly different solution, you might want to check out cryptdb:
http://css.csail.mit.edu/cryptdb/

Steps to publish Software to be purchased via Registration

I'm about to get finished developing a windows application which I want to release as shareware. It was developed in C# and will be running on .Net 3.5+ machines.
To use it the user will have to be online.
My intent is to let the user try it for 30 days and then limit its functionality until a registration is purchased.
The installer will be made available via an msi file.
Could anyone give the general steps on how to implement this?
Here are some more specific questions:
Since I am trying to avoid having to invest a lot upfront in order to establish an e-commerce site, I was thinking of a way to just let the user pay somehow, while supplying his email in which he then receives the unlock key.
I found some solutions out there like listed here:
Registration services
I am still not sure, if they are the way to go.
One of my main concerns is to prevent the reuse if a given serial, e.g. if two users run the program with the same serial at the same time, this serial should disabled or some other measure be taken.
Another point is, that my software could potentially be just copied from one computer to the other without using an installer, so to just protect the installer itself will not be sufficient.
Maybe someone who already went though this process can give me some pointers, like the general steps involved (like 1. Get domain, 2. Get certain kind of webhost ....) and address some of the issues I mentioned above.
I'm thankful for any help people can give me.
I don't have a useful answer for you, but I did have a couple observations I wanted to share that were too large to fit in a comment. Hopefully someone else with more technical expertise can fill in the details.
One of my main concerns is to prevent the reuse if a given serial, e.g. if two users run the program with the same serial at the same time, this serial should disabled or some other measure be taken.
To ensure that two people aren't using the same serial number, your program will have to "phone home." A lot of software does this at installation time, by transmitting the serial number back to you during the installation process. If you want to do it in real time, your application will have to periodically connect to your server and say "this serial number is in use."
This is not terribly user friendly. Any time that the serial number check is performed, the user must be connected to the Internet, and must have their firewall configured to allow it. It also means that you must commit to maintaining the server side of things (domain name, server architecture) unchanged forever. If your server goes down, or you lose the domain, your software will become inoperative.
Of course, if a connection to your service specifically (rather than the Internet in general) is essential to the product's operation, then it becomes a lot easier and more user friendly.
Another point is, that my software could potentially be just copied from one computer to the other without using an installer, so to just protect the installer itself will not be sufficient.
There are two vectors of attack here. One is hiding a piece of information somewhere on the user's system. This is not terribly robust. The other is to check and encode the user's hardware configuration and encode that data somewhere. If the user changes their hardware, force the product to reactivate itself (this is what Windows and SecuROM do).
As you implement this, please remember that it is literally impossible to prevent illegal copying of software. As a (presumably) small software developer, you need to balance the difficulty to crack your software against the negative effects your DRM imposes on your users. I personally would be extremely hesitant to use software with the checks that you've described in place. Some people are more forgiving than I am. Some people are less so.
The energy and effort to prevent hacks from breaking your code is very time consuming. You'd be better served by focusing on distribution and sales.
My first entry into shareware was 1990. Back then the phrase was S=R which stood for Shareware equals Registered. A lot has changed since then. The web is full of static and you have to figure out how to get heard above the static.
Here's somethings I've learned
Don't fall in love with your software. Someone will always think it should work differently. Don't try and convert them to your way of thinking instead listen and build a list of enhancements for the next release.
Learn how to sell or pay someone to help you sell your stuff
Digital River owns most of the registration companies out there
Create free loss leaders that direct traffic back to you
Find a niche that is has gone unmet and fill it
Prevent copying: base the key on the customer's NIC MAC. Most users will not go to the trouble of modifying their NIC MAC. Your app will have a dialog to create and send the key request, including their MAC.
The open issue is that many apps get cracked and posted to warez sites. Make this less likely by hiding the key validation code in multiple places in your app. Take care to treat honest users with respect, and be sure your key validation does not annoy them in any way.
Make it clear that the key they are buying is node locked.
And worry about market penetration. Get a larger installed base by providing a base product that has no strings attached.
cheers -- Rick

Software protection for small vendors

This is a problem we all have to consider at some point.
After many years and many approaches I tend to agree in general with the staterment:
"For any protected software used by more than a few hundred people, you can find a cracked version. So far, every protection scheme can be tampered with."
Does your employer enforce the use of anti-piracy software?
Further, every time I post about this subject, some one will remind me;
"First of all, no matter what kind of protection you'll employ,a truly dedicated cracker will, eventually, get through all of the protective barriers."
What's the best value for money c# code protection for a single developer
So not withstanding these two broadly true disclaimers, lets talk about "protection"!
I still feel that for smaller apps that are unlikely to warrent the time and attention of a skilled cracker, protection IS a worthwhile exercise.
It seems obvious that no matter what you do, if the cracker can switch the outcome of an IF statement (jmp) by patching the application, then all the passwords and dongles in the world anre not going to help.
So My approach has been to obfuscate the code with virtualization using products like:
http://www.oreans.com/codevirtualizer.php
I have been very happy with this product. To my knowledge it has neve been defeated.
I can even compress the executable with PEcompact
Does anyone else have experience with it?
Had nothing but problems with EXEcryptor
http://www.strongbit.com/news.asp
Even the site is a headache to use.
The compiled apps would crash when doing any WMI calls.
This approach allows you to surround smaller sections of code with the obfuscation and thus protect the security checking etc.
I Use the online authorization approach, as the application needs data from the server regularly so it makes no sense for the user to use it off line for extended periods. By definition, the app is worthless at that point, even if it is cracked.
So a simple encrypted handshake is plenty good. I just check it occasionally within the obfuscation protection. If the user installs the app on a different machine, a New ID is uploaded upon launch and the server disables the old ID and returns a new authorization.
I also use a hash of the compiled app and check it at launch to see if a single bit has changed, then open the app as a file (with a read LOCK) from within the app to prevent anyone changing it once launched.
Since all static strings are clearly visible in the .exe file, I try to be generic with error messages and so forth. You will not find the string "Authorization failed" anywhere.
To protect against memory dumps, I use a simple text obfuscation technique (like XOR every character) This makes plain text data in memory harder to distinguish from variables and so forth.
Then of course there is AES for any data that is really sensitive. I like counter mode for text as this results in no repeating sequences revealing underlying data like a sequence of white spaces.
But with all these techniques, if the Key or Initialization vector can be dumped from memory, or the IF statement bypassed, everything is wasted.
I tend to use a switch statement rather than a conditional statement. Then I create a second function that is basically a dead end instead of the function that actually performs the desired task.
Another idea is to code pointers with a variable added. The variable is the result of the authorization (usually zero). This will inevitable lead to a GPF at some point.
I only use this as a last resort after a few lower level authorizations have failed otherwise real users may encounter it. Then the reputation of your software is lowered.
What techniques do you use?
(this is NOT a thread debating the merits of implementing something. It is designed for those that have decided to do SOMETHING)
I disagree xsl.
We protect our code, not because we want to protect our revenue - we accept that those who would use if without a license probably would never pay for it anyway.
Instead, we do it to protect the investment our customers have made in our software. We believe that the use of our software makes them more competative in their market place and that if other companies have access to it without paying they have an unfair advantage - ie, they become as competative without having the overhead of the licensing cost.
We are very careful to ensure that the protection - which is home grown - is as unobtrusive as possible to the valid users, and to this end we would never consider 'buying in' an off the shelf solution that may impact this.
You don't need a few hundred users to get your software cracked. I got annoyed at having my shareware cracked so many times, so as an experiment I created a program called Magic Textbox (which was just a form with a textbox on it) and released it to shareware sites (it had its own PAD file and everything). A day later a cracked version of Magic Textbox was available.
This experience made me pretty much give up trying to protect my software with anything more than rudimentary copy protection.
I personally use the code techniques discussed here. These tricks have the benefit of inconveniencing pirates without making life more difficult for your legitimate end-users
But the more interesting question isn't "what", but "why". Before a software vendor embarks on this type of exercise, it's really important to build a threat model. For example, the threats for a low-priced B2C game are entirely different to those for a high-value B2B app.
Patrick Mackenzie has a good essay where he discusses some of the threats, including an analysis of 4 types of potential customer. I recommend doing this threat analysis for your own app before making choices about protecting your business model.
I've implemented hardware keying (dongles) before myself, so I'm not totally unfamiliar with the issues. In fact, I've given it a great deal of thought. I don't agree with anyone violating copyright law, as your crackers are doing. Anyone who doesn't want to legally aquire a copy of your software should do without. I don't ever violate software copyright myself. That being said...
I really, really dislike the word "protect" used here. The only thing you are trying to protect is your control. You are not protecting the software. The software is just fine either way, as are your users.
The reason that keeping people from copying and sharing your software is such an unholy PITA is that preventing such activites is unnatural. The whole concept of a computer revolves around copying data, and it is simple human nature to want to share useful things. You can fight these facts if you really insist, but it will be a lifelong fight. God isn't making humans any differently, and I'm not buying a computer that can't copy things. Perhaps it would be better to find some way to work with computers and people, rather than fighting against them all the time?
I, along with the majority of professional software developers, am employed full time by a company that needs software developed so that it can do its business, not so it can have a "software product" with artificial scarcity to "sell" to users. If I write something generally useful (that isn't considered a "competive advantage" here), we can release it as Free Software. No "protection" is needed.
From some of the links:
The concept I tried to explain is what I call the “crack spread”. It doesn’t matter that a crack (or keygen, or pirated serial, or whatever) exists for your application. What matters is how many people have access to the crack.
Where/when to check the serial number: I check once on startup. A lot of people say “Check in all sorts of places”, to make it harder for someone to crack by stripping out the check. If you want to be particularly nasty to the cracker, check in all sorts of places using inlined code (i.e. DON’T externalize it all into SerialNumberVerifier.class) and if at all possible make it multi-threaded and hard to recognize when it fails, too. But this just makes it harder to make the crack, not impossible, and remember your goal is generally not to defeat the cracker. Defeating the cracker does not make you an appreciable amount of money. You just need to defeat the casual user in most instances, and the casual user does not have access to a debugger nor know how to use one.
If you’re going to phone home, you should be phoning home with their user information and accepting the serial number as the output of your server’s script, not phoning home with the serial number and accepting a boolean, etc, as the output. i.e. you should be doing key injection, not key verification. Key verification has to ultimately happen within the application, which is why public key crypto is the best way to do it. The reason is that the Internet connection is also in the hands of the adversary :) You’re a hosts file change away from a break-once, break-everywhere exploit if your software is just expecting to read a boolean off the Internet.
Do not make an “interesting” or “challenging” protection. Many crackers crack for the intellectual challenge alone. Make your protection hard to crack but as boring as possible.
There are some cracks which search for byte patterns in search for the place to patch. They usually aren’t defeated by a recompile, but if your .EXE is packed (by ASProtect, Armadillo, etc) these kind of cracks must first unpack the .EXE.. and if you use a good packer such as ASProtect, the cracker will be able to unpack the EXE manually using an assembly level debugger such as SoftICE, but won’t be able to create a tool which unpacks the .EXE automatically (to apply the byte patches afterwards).
I have used .NET Reactor in the past with good results - http://www.eziriz.com/
What I liked about this product is that it did not require you to obfuscate the code in order to have pretty good protection.
xsl, that is a very narrow point of view with MANY built in assumtions.
It seems obvious to me that any app that relies on delivering something from a server under your control should be able to do a fairly good job of figuring our who has a valid account!
I am also of the belief that regular updates (meaning a newly compiled app with code in different locations) will make cracked vesrions obsolete quickly. If your app communicates with a server, launching a secondary process to replace the main executable every week is a piece of cake.
So yes, nothing is uncrackable, but with some clever intrinsic design, it becomes a moot point. The only factor that is significant is how much time are the crackers willing to spend on it, and how much effort are your potential customers willing to exert in trying to find the product of their efforts on a weekly or even daily basis!
I suspect that if your app provides a usefull valuable function then they will be willing to pay a fair price for it. If not, Competitive products will enter the market and your problme just solved itself.

Resources