How can I use a USB key to secure my application? - security

Is using a USB key to secure an application the best option?
If it isn't, what is the best way to secure an application in the form of requiring a valid user before the application can be used?
The reason I ask this question is that a client recently asked me to make an application require a specific USB device be inserted into the system before the app can be used or run. Basically, the application is a medical software and the client sees this method of security more trusted, as the app contains sensitive data of his paients. In that case of loss, I can tell the user how to generate another security key using the app in command line mode.

Not necessarily an answer to the question, but a point to be considered in response to the question and comments so far...
A USB key by itself is not going to be more secure than password-based authentication. It's still one-factor, it can be lost/stolen/etc. What the client probably actually wants, and either doesn't know it or hasn't properly articulated it, is multi-factor authentication. Consider these:
Something you know (a password, answer to a question, etc.)
Something you have (a USB key, time-limited key generating fob, etc.)
Something you are (finger print, retina scan, etc.)
Most systems use only the first one. For added security, you add the second one. For Mission: Impossible style high-clearance security, throw in the third one. The idea is that any one factor can be forged, but adding new factors adds new dimensions of security which exponentially make it more difficult (rather than linearly more difficult when just replacing one factor with a "better" factor).

Your application could require a certificate, signed by you, to be present on a regular USB memory stick. The certificate could be locked with a password, that the user would have to enter. Certificates on stolen or lost thumbdrives could be revoked.
For a less homebrew solution, I'm sure there are commercial smart card based services you could use.

Related

Is it possible to bind a TPM key to a specific application

I'm just starting to learn about TPMs and was wondering if it's possible to restrict a signing key to a particular application? The idea being that only the application that created the key may use it to encrypt/decrypt data.
I believe there is analogous feature on MacOS that relies on having the application binary signed, and access is enforced by the keychain. Something like this is what I'm trying to mimic
TPM is an input-output device and it does not have a way to somehow reach back to the operating system and verify the application sending the command.
You have a couple of options, neither of which is exactly what you're looking for:
If you can have your application start as a system service on boot, then you could have the bootloader, or the kernel, measure your application into a PCR and then bind access to the key you want to restrict to that PCR configuration; then once the application has access to the key, it extends the PCR again. This approach guarantees that only your application can access the key, but it requires cooperation from the system firmware, the bootloader and the kernel and is quite complicated, as you will have to deal with PCR fragility going forward -- you will need to rebind access to the key every time any of the components in the system chain of trust change.
You could protect access to the key with a password, which only your application can provide. Now you have to figure out how to implement access to the password -- whether it's making the user type it in, or communicate with an authenticated service or something else. This approach is much easier to implement, but seems further removed from what you're looking for.

How does PasswordVault protect passwords? [duplicate]

I'd like to use Windows.Security.Credentials.PasswordVault in my desktop app (WPF-based) to securely store a user's password. I managed to access this Windows 10 API using this MSDN article.
I did some experiments and it appears that any data written to PasswordVault from one desktop app (not a native UWP app) can be read from any other desktop app. Even packaging my desktop app with Desktop Bridge technology and thus having a Package Identity does not fix this vulnerability.
Any ideas how to fix that and be able storing the app's data secure from other apps?
UPDATE: It appeared that PasswordVault adds no extra security over DPAPI. The case is closed with a negative result.
(this is from what I can understand of your post)
There is no real way of preventing data access between desktop apps when using these kind of API's http://www.hanselman.com/blog/SavingAndRetrievingBrowserAndOtherPasswords.aspx tells more about it. You'd probably just want to decrypt your information.
memory access restriction is difficult, code executed by the user is always retrievable by the user so it would be difficult to restrict this.
have you considered using the Windows Data Protection API :
https://msdn.microsoft.com/en-us/library/ms995355.aspx
grabbed straight from the source
DPAPI is an easy-to-use service that will benefit developers who must provide protection for sensitive application data, such as passwords and private keys
WDPAPI uses keys generated by the operating system and Triple DES to encrypt/decrypt your data. Which means your application doesn't have to generate these keys, which is always nice.
You could also use the Rfc2898DeriveBytes class, this uses a pseudo-random number generator to decrypt your password. It's safer than most decrypters since there is no practical way to go back from the result back to the password. This is only really useful for verifying the input password and not retrieving it back again. I have never actually used this myself so I would not be able to help you.
https://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes(v=vs.110).aspx
see also this post which gives a way better explanation than I can.
How to securely save username/password (local)?
If I misunderstood the question in some way, tell me, I will try to update the answer.
NOTE that modern/metro apps do not have this problem, although they still are accessible in other ways.
The hard truth is that storing a password in a desktop application, 100% securely is simply not possible. However, you can get close to 100%.
Regarding your original approach, PasswordVault uses the Credential Locker service which is built into windows to securely store data. Credential Locker is bound to the user's profile. Therefore, storing your data via PasswordVault is essentially equivalent to the master password approach to protecting data, which I talk about in detail further down. Only difference is that the master password in that case is the user's credentials. This allows applications running during the user's session to access the data.
Note: To be clear, I'm strictly talking about storing it in a way that allows you access to the plain text. That is to say, storing it in an encrypted database of any sort, or encrypting it yourself and storing the ciphertext somewhere. This kind of functionality is necessary in programs like password managers, but not in programs that just require some sort of authentication. If this is not a necessity then I strongly recommend hashing the password, ideally per the instructions laid out in this answer by zaph. (Some more information in this excellent post by Thomas Pornin).
If it is a necessity, things get a bit more complicated: If you want to prevent other programs (or users I suppose) from being able to view the plaintext password, then your only real option is to encrypt it. Storing the ciphertext within PasswordVault is optional since, if you use good encryption, your only weak point is someone discovering your key. Therefore the ciphertext itself can be stored anywhere. That brings us to the key itself.
Depending on how many passwords you're actually trying to store for each program instance, you might not have to worry about generating and securely storing a key at all. If you want to store multiple passwords, then you can simply ask the user to input one master password, perform some salting and hashing on that, and use the result as the encryption key for all other passwords. When it is time for decryption, then ask the user to input it again. If you are storing multiple passwords then I strongly urge you to go with this approach. It is the most secure approach possible. For the rest of my post however, I will roll with the assumption that this is not a viable option.
First off I urge you not to have the same key for every installation. Create a new one for every instance of your program, based on securely generated random data. Resist the temptation to "avoid having to store the key" by having it be generated on the fly every time it is needed, based on information about the system. That is just as secure as hardcoding string superSecretKey = "12345"; into your program. It won't take attackers long to figure out the process.
Now, storing it is the real tricky part. A general rule of infosec is the following:
Nothing is secure once you have physical access
So, ideally, nobody would. Storing the encryption keys on a properly secured remote server minimizes the chances of it being recovered by attackers. Entire books have been written regarding server-side security, so I will not discuss this here.
Another good option is to use an HSM (Hardware Security Module). These nifty little devices are built for the job. Accessing the keys stored in an HSM is pretty much impossible. However, this option is only viable if you know for sure that every user's computer has one of these, such as in an enterprise environment.
.Net provides a solution of sorts, via the configuration system. You can store your key in an encrypted section of your app.config. This is often used for protecting connection strings. There are plenty of resources out there on how to do this. I recommend this fantastic blog post, which will tell you most of what you need to know.
The reason I said earlier not to go with simply generating the key on the fly is because, like storing it as a variable in your code, you rely exclusively on obfuscation to keep it secure. The thing about this approach is that it usually doesn't. However, sometimes you have no other option. Enter White Box cryptography.
White box cryptography is essentially obfuscation taken to the extreme. It is meant to be effective even in a white-box scenario, where the attacker both has access to and can modify the bytecode. It is the epitome of security through obscurity. As opposed to mere constant hiding (infosec speak for the string superSecretKey approach) or generating the key when it is needed, white box cryptography essentially relies on generating the cipher itself on the fly.
Entire papers have been written on it, It is difficult to pull off writing a proper implementation, and your mileage may vary. You should only consider this if you really really really want to do this as securely as possible.
Obfuscation however is still obfuscation. All it can really do is slow the attackers down. The final solution I have to offer might seem backwards, but it works: Do not hide the encryption key digitally. Hide it physically. Have the user insert a usb drive when it is time for encryption, (securely) generate a random key, then write it to the usb drive. Then, whenever it is time for decryption, the user only has to put the drive back in, and your program reads the key off that.
This is a bit similar to the master password approach, in that it leaves it up to the user to keep the key safe. However, it has some notable advantages. For instance, this approach allows for a massive encryption key. A key that can fit in a mere 1 megabyte file can take literally billions of years to break via a brute force attack. Plus, if the key ever gets discovered, the user has only themselves to blame.
In summary, see if you can avoid having to store an encryption key. If you can't, avoid storing it locally at all costs. Otherwise, your only option is to make it as hard for hackers to figure it out as possible. No matter how you choose to do that, make sure that every key is different, so even if attackers do find one, the other users' keys are safe.
Only alternative is to encrypt password with your own private key stored somewhere in your code. (Someone can easily disassemble your code and get the key) and then store encrypted password inside PasswordVault, however the only security you have is any app will not have access to password.
This is dual security, in case of compromised machines, attacker can get access to PasswordVault but not your password as they will need one more private key to decrypt the password and that will be hidden somewhere in your code.
To make it more secure, if you leave your private key on your server and expose an API to encrypt and decrypt password before storing in Vault, will make it most secure. I think this is the reason people have moved on to OAuth (storing OAuth token in PasswordVault) etc rather then storing password in vault.
Ideally, I would recommend not storing password, instead get some token from server and save it and use that token for authentication. And store that token in PasswordVault.
It is always possible to push the security, with miscellaneous encryption and storage strategies. Making something harder is only making the data retrieval longer, never impossible. Hence you need to consider the most appropriate level of protection considering execution cost x time (human and machine) and development cost x time aspects.
If I consider strictly your request, I would simply add a layer (class, interface) to cipher your passwords. Best with asymmetrical encryption (and not RSA). Supposing the other softs are not accessing your program data (program, files OR process), this is sufficient. You can use SSH.NET (https://github.com/sshnet/SSH.NET) to achieve this quickly.
If you would like to push the security and give a certain level of protection against binary reverse-engineering (including the private key retrieval), I recommend a small (process limited) encrypted VM (like Docker, https://blogs.msdn.microsoft.com/mvpawardprogram/2015/12/15/getting-started-with-net-and-docker/) based solution such as Denuvo (https://www.denuvo.com/). The encryption is unique per customer and machine based. You'll have to encapsulated you c# program into a c/c++ program (which acts like a container) that will do all the in-memory ciphering-deciphering.
You can implement your own strategy, depending on the kind of investment and warranty you require.
In case your program is a backend program, you can pick the best strategy (the only I really recommend) of all which is to store the private key at the client side, public key at backend side and have local deciphering, all transmitted password would be hence encrypted. I would like to remark that password and keys are actually different strategies to achieve the same goal: checking if the program talks to the right person without knowing the person's identity; I mean this: instead of storing passwords, better store directly public keys.
Revisiting this rather helpful issue and adding a bit of additional information which might be helpful.
My task was to extend a Win32 application that uses passwords to authenticate with an online service with a "save password" functionality. The idea was to protect the password using Windows Hello (UserConsentVerifier). I was under the impression that Windows surely has something comparable to the macOS keychain.
If you use the Windows Credential Manager APIs (CredReadA, CredWriteA), another application can simply enumerate the credentials and if it knows what to look for (the target name), it will be able to read the credential.
I also explored using DPAPI where you are in charge of storing the encrypted blob yourself, typically in a file. Again, there seems to be no way (except obfuscation) to prevent another application from finding and reading that file. Supplying additional entropy to CryptProtectData and CryptUnprotectData again poses the question of where to store the entropy (typically I assume it would be hard-coded and perhaps obfuscated in the application: this is security by obscurity).
As it turns out, neither DPAPI (CryptProtectData, CryptUnprotectData) nor Windows Credential Manager APIs (CredRead, CredWrite) can prevent another application running under the same user from reading a secret.
What I was actually looking for was something like the macOS keychain, which allows applications to store secrets, define ACLs on those secrets, enforce biometric authentication on accessing the secret, and critically, prevents other applications from reading the secrets.
As it turns out, Windows has a PasswordVault which claims to isolate apps from each other, but its only available to UWP apps:
Represents a Credential Locker of credentials. The contents of the locker are specific to the app or service. Apps and services don't have access to credentials associated with other apps or services.
Is there a way for a Win32 Desktop application to access this functionality? I realize that if a user can be brought to install and run a random app, that app could probably mimic the original application and just prompt the user to enter the secret, but still, it's a little disappointing that there is no app-level separation by default.

Payment application based on NTAG213 vs. Ultralight C (using Android NFC)

I have a (university) project where I basically write and read text out of an NFC tag with Android devices in order to store one's balance in the card (which can be used on the cafeteria, for example).
Right now, I'm using NTAG213 doing the below code:
ndef.connect();
NdefRecord mimeRecord = NdefRecord.createMime("text/plain", messageEncrypted.getBytes(Charset.forName("US-ASCII")));
ndef.writeNdefMessage(new NdefMessage(mimeRecord));
ndef.close();
As you can notice, I'm using application level encryption to encrypt the message (messageEncrypted) before writing it to the tag (AES-256 encrypt with 'com.scottyab:aescrypt:0.0.1' library - with a very big password key that uses also the tag UID as part of it).
So far so good - only I can understand the data on the tag.
On my research, I've found that when it comes to security Ultralight C > NTAG213.
Question 1) When using application level encryption, why (is it?) is MIFARE Ultralight C safer then NTAG213?
Question 2) I'm pretty sure I can guarantee security using AES encryption, but I don't want people (besides me) messing with the stored data (formatting tag or writing info there). I see that the only way of preventing that (please, correct me if I'm wrong) is to set a password for the tag. However, both NTAG213 and Ultralight C have only an 32-bit password. Is it good enough? Is there another way of preventing someone (besides me) writing data?
Question 3) Which other security measures can I use on such tags to enforce security (tag and application layer)?
Question 4) When you compare tag security (MIFARE DESFire > Ultralight > NTAG213 > MIFARE Classic), what is really being compared? The ease of one cracking the (native tag's) encryption or the ease of one store (anything) on the tag without permission?
Question 5) I see a bunch of other techs (MIFARE DESFire, ICODE SLIX, Infineon Cipurse) that are more secure, which makes me wonder if the tech I'm using (NTAG213 or Ultralight C) is good enough for storing someones balance. Would you (and that's a personal opinion) say that NTAG213 with application level encryption and 32-bit password good enough for this type of application? And how long would it take someone to actually break its security?
When using application level encryption, why is Ultralight C safer then NTAG213? Is that even true?
First of all, "safer" depends on what your actual protection goals are. Since you want to store a balance (cash money!) on the card, you would probably want to (at least) protect towards the following goals:
Users must not be able to print their own money by setting an arbitrary balance on their card.
Users must not be able to duplicate their card and, consequently, their money balance.
Users must not be able to print their own money by restoring (roll-back) their card to a previous balance after payment.
Users must not be able to print their own money by replaying a top-up procedure.
Users must not be able to evade payment by tearing their card during a payment transaction.
Users must not be able to generate an arbitrary (and potentially higher) balance on their card by tearing their card during a top-up procedure.
In addition, you might not want to trust operators (the persons accepting payments and performing top-up) as well. In a system where one group of operators performs only top-up and the other performs only payment transactions, the latter group should probably not be allowed to ever "create" money. Particularly, you have to make yourself very clear about whether you fully trust the (Android) devices that you use in the field to perform these operations and whether you trust operators (e.g. that they don't perform any attacks against these devices).
Moreover, there might be privacy aspects that you need to consider (e.g. if the balance is freely readable, if users are identifiable, etc.)
So let's look into what you "application level encryption" adds in terms of security:
Since users do not know the encryption key, they are probably not able to generate an arbitrary balance on their card. However, this heavily depends on the format of your balance (in unencrypted form). Users can make arbitrary modifications to the cipher text with result in "random" modifications of the plain text. Consequently, users may be able to modify the balance value despite encryption. Digital signature/message authentication codes are they path that you would probably want to take to overcome this.
Since the encryption key (assuming encryption would be sufficient, which it probably is not) depends on the UID of the tag, you may be safe against cloning of cards (+ balance). However, be aware that the UID is just a freely readable identifier. It is by no means authenticated itself and may be clonable as well. See Serials on NFC Tags - truly unique? cloneable?.
The encrypted value does not protect you from users restoring their balance to a previously recorded value after payment. This type of vulnerability has been found before (particularly in MIFARE Ultralight based systems), see, for instance, Benninger, C., Sobell, M. (2012): NFC for free rides and rooms (on your phone). In: Presentation at EUSecWest 2012.
Since you write the complete value during a top-up procedure (i.e. there is no specific "increment balance" command), you are probably safe against users replaying a top-up (except for the roll-back aspect of this).
Effects of tearing are probably rather limited if your system only allows for attended payment/top-up.
So let's see what additional features NTAG213 would have that you could use to secure your system:
UID is unique on genuine tags. This does not help much, see Serials on NFC Tags - truly unique? cloneable?.
Originality signature: same as above, the originality signature is also just a static, freely readable value. Consequently, it's just as well susceptible to cloning.
The one-way counter might be a tool to help you in protecting against roll-back (by including the counter value into the signature). This still would not prevent cloning onto a tag platform that allows to generate arbitrary counter values. Moreover, the counter is not easily controllable and will change its value if the user tries to read the tag. Consequently, it's questionable if an implementation based on that value would be reliable.
Unlike MIFARE Ultralight, NTAG213 does not have a usable one-time programmable area (since that's already used by the capability container). Consequently, you can't implement a one-time deductible balance based on that.
The password protection feature could help you in authenticating tags (by performing password verification) and in protecting the value stored on the tag (by making the value only readable/writable after password verification). However, the password is transmitted in clear text (may be subject to sniffing, particularly in (but not limited to) unattended scenarios) and there is no cryptographic binding between the password and the actual read/write.
MIFARE Ultralight C would add the following:
The OTP bytes can be used. If it's an option to make the tags one-time usable (i.e. they start with a specific balance that can only be deducted from and not topped-up), then using the OTP bytes to represent the balance would be an option. Note that there's still lots of things that you could do wrong with that, e.g. Beccaro, M., Collura, M. (2013): OTP circumventing in MIFARE ULTRALIGHT: Who says free rides?. In: Presentation at DEFCON 21
The authentication is much improved. The 3DES authentication scheme seems to be sufficiently secure to prevent sniffing the key. However, read/write commands are also not cryptographically bound to the authentication step. Consequently, an attacker might be able to let a genuine payment terminal + genuine tag perform authentication, but redirect read/write to somewhere else. This might (particularly) be a problem in an unattended scenario.
I'm pretty sure I can guarantee security using AES encryption.
See above. This is probably not true.
I don't want people messing with the stored data. I see that the only way of preventing that is to set a password for the tag.
A password/authentication key may help, but be aware of the limitations due to authentication being decoupled from read/write on these tag platforms.
Both NTAG213 and Ultralight C have only a 32-bit password.
This is not true. NTAG213 has a 32-bit password. MIFARE Ultralight C uses a more sophisticated mutual 2K-3DES authentication mechanism with a 112-bit key.
When you compare tag security, what is really being compared?
Authentication mechanisms (algorithms, key sizes)
Communication security (e.g. is the communication itself encrypted/authenticated using a session key derived from the authentication step?)
Access control (e.g. are there separate keys for top-up and payment?)
Are there dedicated mechanisms for balance management (e.g. value fields, dedicated increment/decrement operations)? And, consequently, are ther mechanisms to protect agains tearing attacks?
And probably more ...
I see a bunch of other techs that are more secure, which makes me wonder if the tech I'm using is good enough for storing someones balance.
You specific system is flawed in many ways. In my opinion MIFARE Ultralight/NTAG203/NTAG21x are definitely not a good choice for a an offline system storing cash money on the cards.
MIFARE Ultralight C may be suitable with some precautions. I would definitely refrain from using that in unattended scenarios, and I would probably use an online system tracking the balance and monitoring for inconsistencies.
Anything that uses symmetric cryptography and storing the cryptographic keys in a terminal would certainly require precautions against malicious operators. It's probably fairly easy for an operator (with some knowledge) to extract keys from an app and generate their own money.
I guess your question is too broad and not for all subquestions this section of SO is the most appropriate one.
By focusing on cryptographic strength you miss something: if the low level security of the token can be easily attacked, nobody needs to crack your key.
A simple dump and later restore (after some payments) corresponds to printing money
If the token contains the money directly (instead of only identifying the wallet, which is stored on a background system), you need a far more secure system to avoid financial damage. This involves dynamically encrypted communication but continues with substantial further topics.

What is the best way to secure your program

I searched a lot about what is the best way to secure your program and I found many results and there were two good ways.
The first one is to hash the mac address of the computer and link it with an activation code but it's still vulnerable.
And the second one is to use a usb device but I didn't find any detail so can anybody tell me in details what is the best way and how to implement it please.
First of all, you need to consider that it doesn't matter what you do, someone will be able to crack it, and because of this is that you need to consider a balance between the security of your application and how hard you will make it for legitimate users (since you don't want to punish a user who already paid for your product, just because you want to protect your applications from the guys who don't want to pay).
Having this in mind, you could go with digital signatures using asymmetric encryption, where you'll sign your license "activation" with your private key, and then your application will use its public key to verify that the received license was submitted by you. You should also take a look at this discussion (I recommend you to focus on the 2nd answer, not the selected one) and this one.
But again, your objective should be to just make things hard for bad guys, but without punishing your legitimate users, because for an attacker, it could be as easy as de-compiling your program and removing your logic to validate the license (unless you're creating an "always online" application, but usually users don't like that, and I'm saying this as a user).

License scheme, spoof-safe and revoke capabilities

this is my first question so please be gentle...
I am working on a software which I would like to protect using some kind of licensing scheme.
A basic scheme would be to generate some "unique" key for a user. The user sends this key and a registration code when he wants to register the software and receives an activation code.
When the application runs it validates the activation code by comparing the "unique" key and a datablob received by decrypting the activation code.
This is fair and quite simple to implement, one can choose different crypto algorithms etc. however this scheme lacks two properties:
If the user manages to spoof hardware signature etc. to produce the same "unique" key on another computer he could use the same license data.
If the user decides to uninstall the application and wants to move it to another computer, there is nothing that prevents him from using the old license data again at the old computer and still obtaining new license data for the new installation.
Do you have any suggestions on how to resolve these issues?
One idea I had was to add some random data to the "unique" key, this random data would be stored in an obscure way, if the user deinstalls the application this random data would be removed, and some kind of hash with the previous random data and the license data would be generated which could be sent to me to verify that he really have uninstalled the application and made me sure that he wont be able to use the previous license data again since the random data had changed.
Over and out, for now...
EDIT:
I currently have a scheme that works, I should mention that the most common product is installed in an embedded enviroment where hardware-changes are very rare and if there is a hardware failure then most certain the machine is broken. But I could modify the hardware-key scheme to take into account and allow for some changes.
Also because of this the software will most likely not be run inside a VM, good point though and I haven't thought about that.
The application does not call out regularly, if a network connection is available the user gets the option to make a more automatic registration, otherwise he/she gets a registration key, enters it in the software and gets an installation ID which is provided to me, registration code + installation ID generates an activation key that the user gets from me which then unlocks the software.
What I am looking for is good/feasible solutions to the 2 points. Hardware spoofing, Revoking license keys i.e. to be sure the user can not use the same regcode+activationcode.
Thank you for all your feedback
It is not necessary to
First, you should make it clear what you're trying to protect. Apparently, you want to ensure that for each purchase of your application, there will only ever be one computer on which the application is installed and runnable.
You propose to use a hardware signature as part of each user's unique key. What happens if my hardware fails (e.g. my hard disk breaks)? I'm certainly not going to purchase your application if I can't go on using it after a hardware problem, so at a minimum you must be prepared to handle key change requests. You'd better respond fast, because if your application is important I want to minimize downtime. And I'm not inviting you to check that my hardware has failed, so you'll have to take my word for it. That means any user can get a free licenses from time to time by pretexting a hardware failure.
What about virtual machines? It's probably feasible to detect all currently existing virtual machine configuration, at the risk of a few false positives now and then. If you forbid virtual machines, how do you justify this to users? If you allow virtual machines, how do you prevent the user from making multiple copies of the whole VM? (This can happen even with physical machines, with hibernation).
Is the application going to call back to you every time it starts? I guess so, from your deinstallation scheme. That's a bandwidth and availabilty cost, and will also put off some users — not everyone is online, especially in sensitive environments. But then you don't need such a complex scheme: your server can keep track of how many copies of the application are running, though you do have to handle the case when the application doesn't terminate cleanly for any reason (application crash, OS crash, power failure, loss of connectivity...).
You don't discuss this in your question, but you have to protect the application executable, so that someone can't bypass the license check with a debugger.
Place your software into appliance hardware and put a padlock on the hardware. Ship the appliance to the customer.
If you believe the customer will hacksaw the appliance open to get your code, consider encrypting the storage medium.... Then they have to hacksaw the box AND find the keys. A TPM chip or secure USB token may aid with the latter.
Being a shareware author and longtime member of ASP myself i think you are going into the wrong direction with your solution. The only way to make this workable is with a hardware device as already suggested. This or constant online activations is the only way if you want to be sure and your product is so good and without competitors that your customers will still use it.
But what we (organized small ISV's) learned from practice is that you should not do what you are trying to do. Do not bind it to hardware. Sell one license per person not one license per computer. In the end you will make more sales because of the relaxed license.
Just do enough to make the honest people stay honest. So limit the trail version (i decided to terminate the application after one hour for me) and leave the final version free from all stuff. Give a separate download for payed customers and thats it. Be a nice company and not a greedy profit maximizing by legal restrictions company.
I used some of the better windows protection programs first but they all had serious problems with my code. And they call get cracked sooner or later. So i gave up all of them.
P.S.: I use a hardware fingerprint schema on windows where i don't restrict the program but just to keep people away from getting new trial keys every 30 days. Together with a nag screen it seems to work. The fingerprint is an xor of user name, windows installation time, modify time stamp of a system files and harddisk serial id.
Let the registration code also be the activation code.
You generate the unique registration code at point of sale, or packaged with the product. Customer registers/activates/deactivates with you (or your server) in one step using that single code. The customer's hardware doesn't have to generate any keys.
Reregistering/reactivating still requires contact with you, so you're aware of reinstall attempts.
I think that the only solution to your problem is a cryptographic hardware dongle. Usually it would be a USB-based tamper-resistant challenge-response dongle, that can be easily transferred between computers.
These devices cost less than $1 for large quantities, and not more than $10 for very small quantities. The good ones are very hard to forge, very easy to embed in your application, and usually supplied with a free EXE encryptor which also contains anti-debugging and anti-reverse-engineering functionality.

Resources