Based on accepted answer of this post How can I create a product key for my C# application?
I would better to investigate (for didactic scope) what really means with "security check skip" terms.
As far as I know, a simple boolean comparsion can be cracked within 5 seconds, for example:
if(textBoxActivationKey.Tex == "123") ok...else ko. That represents a classic weakness of any secuirty system solution, so what really can be more efficient against simple comparsion?
Somewhere I remeber to have read to use some exception throwing for crash the application rather then use bool comparer, but I guess it cannot be enough.
Granted that (at least theorically) anything can be cracked, how make it really sofisticated secure activation system? Which can be a real deterrent?
Are you looking for efficiency or effectiveness? Most applications phone home. That seems to be a pretty good activation method. However, this means that the user must be online to activate.
If you must be online, and the activation is done through a service (that you own) on a server somewhere, then you can instantly record that the activation key has been used (and invalidate it).
I'm not an expert on this subject, but I think if the shipped key represents only part of the full activation key and the rest must be received from a server, that might work.
Related
I need to find a way to lock a software product, so only customers who bought it can use it. I was thinking about implementing my own "CD-key" feature.
How it works:
I have a seperate program, that is used only for generating keys.
The program uses the same algorithm than the software being selled. The key is shipped with the program (on lets say the manuals) and entered in the program one time. After that the user can use it freely without ever entering it again(until reinstalling).
This looks pretty simple and doable to me, but the only problem is that the key can be reused on other devices, so I would need to implement a way, that the key is online marked as used and unused, when the program is getting uninstalled.
I would try asking this on https://softwareengineering.stackexchange.com/ instead of here - but I'd advice you to look into (non)-commercial products/API's to help you out (e.g. http://www.ssware.com/cryptolicensing/cryptolicensing_net.htm) in stead of reinventing the wheel. As it's not your core business, you'll likely have a less optimal solution (and thus weak and leaky solution) than what others might provide you with.
Some products you can look into:
free
QLicense (on CodeProject): https://www.codeproject.com/Articles/996001/A-Ready-To-Use-Software-Licensing-Solution-in-Csha
pay to use
SSWare's CryptoLicensing: http://www.ssware.com/cryptolicensing/cryptolicensing_net.htm
SORACO: https://soraco.co/quick-license-manager/?gclid=CjwKEAiAirXFBRCQyvL279Tnx1ESJAB-G-Qvy65J7uzmMUClDy0fltJKN7U9HtFex5akQ-H3r7YgFhoCa7nw_wcB
PS: if you would start implementing a licensing solution on your own, please drop implementing the same algorithm in both the deployed code as well as the generator - it's too easy to reverse engineer. Try to use some mathematical formulas that support public/private key mechanisms for example, or as I said try to rely on a library/api that's specialised in this domain.
Problem:
Since your code can be reverse-engineered, there is not real way to provide safe solution for your key storage. All your variables hard-coded into application, or in separate files, where they are encrypted using the same application are not safe. You need to treat them as publicly available.
Second even if you will provide way of server key authentication, again. Your code can be reverse-engineered. Hacker will remove authentication part, and will re-build your application, DRM free.
Third, even if you whole code, will be crypted, there are still ways to decode that and remove authentication (look denuvo latest failures).
If you will connect code crypting and server side key authentication depending on how many people will be involved in hacking you can delay them be finite amount of time.
Solution:
There are 100% secure ways to prevent your application to be hackable, you need to make it 100% web based. There are solutions like ASP.Net if you wish to use C# as server engine.
I'm currently trying to develop a client-server structure, with the client being in .NET and the server being a PHP based SOAP server.
Now, I'm trying to implement an asymmetric key system using Rijndael 256 and a bit of fiddling about. I understand the basic concept of a public/private key pair (as per this page & Wikipedia), however I cannot get my head around it being secure in any client-side environment.
In short, the software will be running on the client machine, so the user will have the ability to tamper with the software. Most of the client's functionality revolves around responses received from the server in order to display reports & details. Along with that the client software will occasionally await a command from the server, where the server will tell the client to show a pop-up or execute a client-program shutdown (to do with licensing). I realise the server may crash or hang, or the client gets disconnected. Most of this has all been thought over and handled in code. But what I'm worried about is someone tampering with the client so that it completely ignores the server's commands.
The customer will have access to a wide variety of 'toys' such as IDA, ILDASM, de4dot and various other debuggers and/or decompilers and Im fairly certain an experienced cracker will be able to figure out the public/private key combination within a short period of time. I know .NET code on its own is very insecure, but I'm not sure what to do against that other then using tools such as .NET Reactor & Dotfuscator etc.
My question: what sort of practices, code, ideas or anything can I put to use in order to either severely delay said cracker, or rather, how do I protect the private key at all costs.
Any hints, tips, suggestions or samples very appreciated!
As #Corak stated, public/private key pairs usually work by keeping the private key private. On the client side, you can generate a new public/private key pair every time you connect. The easiest data to hide is the data that isn't saved in the first place.
The other part of your question is "how to stop a cracker!" That's not possible because the end-user has full control of the machine. You can play tricks to try to obfuscate your private key in memory, keep it out of the swap file, etc., etc., but any cracker with suitable tools and desire to crack your program will do it.
UNLESS!
You can partner with leading hardware vendors. Have them install a super-secure chip on all their hardware, and this chip will be under your control and not the user's control. When activated, this chip will monitor all I/O and memory and only allow what you decide to allow. Then you can simply disallow programs like IDA, rendering crackers helpless! As a side effect, you also get complete control over the user's computer, and you can use that power however you want. Everyone wins!
One last note: if you do decide to implement this, I recommend that your marketing department put a heavy spin on it. There'll probably be a bunch of jerks whining about "privacy" and "ownership" and crap like that. So you'll need a good name for this technology; the name has to sound like something people would want.
I think you should call it "trustworthy computing" (since "trusted computing" is already taken). Or maybe "secure computing".
I'm developing a program in C#.
It connects to the internet to see if this copy is valid.
Currently I'm just sending the licence key and getting a response (0 or 1) if the key is valid.
The problem is that some users just fake the data with some packet capturing tool and replay it.
So the application is very easy to crack. How can I prevent this?
Here is what I essentially want to prevent:
Network replay attacks
Authentication "emulators"
It should be impossible to find out what data is sent.
Maybe I should add the current time and then encrypt the packet ?
So it's always different ?
Attention: Please don't warn me that it's easy to crack the application itself by modifying it. I know that. This question is only about the network part.
If you use SSL or HTTPS then you don't have to worry about users cracking the data packets. This is easy because the libraries already exist and are easy to implement. With C# and IIs for example it is just a matter of installing the certs and changing a few configuration items. (Maybe a recompile with some slight code changes).
Assuming you actually want to prevent license abuse there are far better ways to do this. The "phone home" approach is easy to roll yourself, but as you've noticed it's full of holes.
Disclaimer: I work for a company that makes commercial tools to solve these license management and copy-protection issues. There are other similar products available from a variety of vendors.
This isn't that different from thinking about how to do setup for your application. Choices are roll your own or buy an existing 3rd party toolset. Rolling your own at first blush make seem cheaper, but that's perhaps only because you haven't really discovered all the true requirements to create something robust and reliable. The 3rd party tool vendor needs to charge for their products, but they've spent years discovering all the issues with particular problem set and have solved the problems. So that eliminates work for you and leaves you free to focus on where your application can add value.
The difference is if you get setup wrong your users will be irritated; if you get copy protection wrong your product will be pirated.
In any event, reducing license validation checking to a binary "either/or" condition is extremely easy to crack--doing that check over the net makes it 10 times easier (record playback attack). Modern approaches encrypt the executable and the license is contained in the key to decrypt it (this is an oversimplification since the actual methodology includes a lot more complexity to make it virtually impossible to get around). Only by having a valid license can the executable be decrypted on program load and run.
If you want to do it the way you've described, consider this:
Have the app use a predictable, changing value (such as a lookup from a table of random numbers coupled with some external value like time) to create some kind of hash. Have the server implement the same code. The server sends the hash to the app, which compares it to its own hash. If they match, the app is allowed to run. If they don't, it errors out. Since the hash is different on ever startup attempt, recording it over the network won't allow the user to get it to run the next time it tries to start.
I am looking for a bit of help. I realize there are many threads that explain the difficulties and problems of uniquely identifying a computer as far as piracy preventions and user licenses. This situation is a tad bit different in the fact that users must have an active account to log in and use the software. And this option will only be on a requested basis not for every account.
The issue arises when some of the companies have requested instead of admin accounts, they would like admin locations. I am looking if there a good way to do this, or if this will still have the same issues of changing hardware/ spoofing MAC's.
Some of the machine need uniquely identifiable we will have remote access to, while others we won't.
We run on a .NET platform
The only way to use our software is active log-in.
Thanks in advance for any help provided.
I agree with other answers but have an additional suggestion:
Every Windows generates unique SID on installation... you can get that via DirectoryEntry in the objectSID item of Properties... see http://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentry.aspx
hope this helps a bit...
EDIT - getting MachineSID as string (corrected as per comment):
string MachineSID = new SecurityIdentifier((byte[])new
DirectoryEntry(string.Format("WinNT://{0},Computer",
Environment.MachineName)).Children.Cast<DirectoryEntry>().First().
InvokeGet("objectSID"),0).AccountDomainSid.Value.ToString();
you need to add a reference to System.DirectoryServices and make sure to have using System.Linq; and using System.Security.Principal; and using System.DirectoryServices;.
It is essentially impossible to prevent people from "spoofing" a location. So plead with the clients to allow for a layer of authentication above the "location" they request.
Short of that you may want to take some loosely identifyable information such as the MAC, IP, or other specs and send it as an encrypted string. Anyone sniffing on the network wont be able to tell what the data being sent is so will have a harder time spoofing it if that is their goal. If they manage to decrypt the message then the data is in the open but until they're able to read it it provides a minor layer of security.
I still recommend against this idea but I'm sure it can be done. There is a truckload of issues you'd be forced to deal with that exist outside the software domain itself and would complicate things much more than a strong authentication scheme. Hopefully other members here can provide good examples to use but you don't want any false positives or otherwise (Dynamic IPs getting in the way etc.)
IMHO, there is no good way to use the hardware as a primary means of authentication. You could do something like have an admin account that should be tied to certain hardware, and then try to heuristically detect changes in hardware but that's a scenario where you have an account AND hardware instead of an account OR hardware.
All preaching aside, if you can't convince the company that it's a bad idea, what I would do is provision those certain machines with keys that you authenticate with. Then you have full control over if/when to allow those keys to authenticate, you can revoke their access, but still give the effect of it being the machine that's authenticating, and not an account. It's still got all of the advantages and flexibility of being software controlled with the same effect of being hardware-based.
Background
I need to implement a simple node-locked licensing mechanism (i.e. the license needs to be valid only for a specific physical computer).
I intend to use an asymmetric cryptographic algorithm such as RSA.
Here is how I intend to organize the basic licensing "workflow":
The application that needs to be licensed reads a piece of data that uniquely identifies the computer (it is currently running on). Let's call this data "computed ID".
User requests the license by sending the computer ID.
Based on the computer ID, the license is generated and protected (either by full encryption or by signing) and sent back to the user.
The application can then compare the license with the actual computer ID and refuse to run if they do not match.
Note that computer ID will not be particularly sensitive (probably just a MAC address and possibly HD serial) and does not represent a secret on its own.
Question
The dilemma I have is whether to:
encrypt the computer ID (both in the license request and in the license itself),
or to include it as a plain text (in both request and license) and just add a signature (in license).
(1) If I choose full encryption, then I'll need two pairs of public/private keys - one for each direction (one for encrypting the request and decrypting it before generating license; and one for encrypting the license and decrypting it by the application).
(2) If I choose to use signature, I just need one key par - private key for signing the license and public key for verifying the signature when application runs (so it knows the plain text computer ID in license did not change).
The approach (2) looks simpler to me, but is it as "strong" as (1)?
I'm implementing this in C#, but I'd like a general "high level" advice on pros and cons of each approach, regardless of the implementation details.
Since this is my area of expertise, let me jump in... It seems you are trying to create your own activation system starting from scratch. May I ask why you are doing so, rather than just using a commercial system?
In the early days of using activation to protect software licenses a number of companies took the approach of developing their own systems without having deep expertise, and their ignorance of what it took to make a secure, user-friendly activation system gave activation a bad name. So, in the interests of helping you not have to painfully re-learn these lessons and irritate your customers, here are some of the things you need to think about:
How will users activate their license if they don't have a network connection to the server, or their connection is blocked by a firewall?
You said you are node-locking your application to some parameters of the user's system. How will you deal with someone who makes a minor upgrade to their system, causing a node-locking parameter to change? Note the MAC address is not a good choice for this, even though it is commonly used, as the ease with which the MAC address can be configured on some systems means MAC-address node-locking is insecure.
A user's system crashes - how can they get their license running on another system? (and how can you know they are telling the truth about their system crash?)
What if a user wants to move their license to another machine after a while, say from their desktop to their laptop. Can your system allow them to do this without it being a security hole or an annoying manual process requiring your support?
How will you secure your licenses against key tampering, spoofing or tampering with the licensing code etc?
From your post it seems you just want to enable the whole application for now. What if in future you want to activate time-limited trial or subscription licenses, configure product features or enable certain modules etc. Will your activation system support this or will you have to re-build it?
Some companies don't want any clear-text information about their systems going over the Internet, so you may want to encrypt the uploaded system details from the get-go.
Just some things to think about.
As your computed id works only on the machine where the computed id can be reproduced it is actually not really a problem if you transport the computed id as plaintext. even if somebody steals it, he wont be able to use it.
If somebody manipulates it through the transport you will recognize it too (as it is signed)
But: it depends what kind of computed id you generate. If you dont use a appropriate algorithm someone could get some information about the system on where the computed id got generated (which wouldnt be appreciated by your licencees)
For that you should use a "save" hash function with no (or non predictable) collisions.