I was introduced to “hwid” a number of times from people who make cheats for online video games, and after doing some research, it has become apparent that hwid is a flawed way to secure your program. Note: any “secure” hardware id check will require an internet connection. If your software could be run offline, disable hwid checks, or run them only when the computer is online. For the people who are making addons or modifications for online games, requiring an internet connection is not a problem, since anyone using their software would have to be online in the first place.

What is hwid?

From what I can tell, operating systems like Windows generate a unique hardware-based identification key when they are installed. Windows stores this key in the registry, and allows any program to access it. Any change to your hardware, even something like moving your RAM into different physical slots, can force this identifier to change. Software programs track your hardware id as part of their licensing scheme, so they can make sure their program isn’t being used on multiple machines.

There are other identifiers that can be used in place of the traditional registry hwid token, such as the CPU ID, hard drive serial number, and network name. However, multi CPU systems (rare) may not work well with a CPU ID system. Multiple hard drive systems (fairly common, especially when you count SSDs) can make a serial number check fail, and network names are the easiest to fake when outside of large organizations.

Most implementations of hardware identification, especially when not done by a professional, fall flat on their face. There are ways to edit the registry (risky), or use another program to spoof the hardware identifiers of your computer. These are incredibly effective at tricking most programs into believing that you are on the same computer that you registered the software to, even if you aren’t. An advanced implementation of a hardware id checker could act like an Antivirus, by looking for spoofing programs that might be running, or evidence of tampering. However, making “antivirus” DRM software is a drain on development resources.

A smarter approach would be to get each of these hardware-linked identifiers, and check to make sure that most match your records. This is much more ideal, but the fewer matches you require is, the easier it is to trick your identification system.

Then there’s also the convenience factor: make your program too strict, and users will be alienated. Make it too open, and you could lose some sales. Studies have been conducted on the effect of DRM on sales and piracy, and the results are generally in favor of weak DRM. Most of these studies, however, are focused on games, music and media. My focus for this post is on software, like Word or Photoshop, which often have different incentives for piracy.

How do I correctly implement a hwid check?

There are a lot of language-specific pitfalls that you should search for online, especially if you’re using a low-level language like C++. This post does not cover all of those problems.

To get started, you will need a server somewhere. This could be an existing web server, but regardless, it must have some sort of certificate for signing and encrypting all requests. Otherwise, it can be faked by editing the Windows hosts file and running a local server. I’ve used PHP for the server, since I’m comfortable with it, and it can easily talk to databases. This also allows me to stick with HTTP requests, instead of special sockets and custom protocols.

Also note, HTTPS requests can still be spoofed. An attacker just needs to generate their own certificate and tell their operating system to trust the “authority” that signed it. Programs like Fiddler make this fairly simple. As a second layer of security, you could encrypt all requests with a private key stored on the webserver and decrypt requests in the software with a public key. This way, even if the would-be pirate generates their own self-signed certificate and their OS trusts said certificate, they still have to get around the fact that the program expects a second layer of encryption.

Next, find the default way to make an HTTPS request in your preferred language, or find a 3rd party library. Whatever you use, it must have a way to verify that the response from the server was signed with the proper certificate. Start simple, by making requests to Google and verifying that you’re actually talking to Google. Then test out your real server. The goal here is that, by verifying every request with a certificate, the easiest target for an attacker is the local machine, and not in the request pipeline.

The mistakes I commonly see are:

  • The programmer put database credentials in the software, and all further checks are done directly on the user’s machine. Oops! Someone decompiled the code and now has total access to your database, even if the access is read only.
  • The request is done without encryption. Oops! Someone knows what response the program is expecting back, and has now made a secondary program that allows anyone to use your software.
  • The hwid authentication is done with only one factor. Oops! Someone did winkey + R and typed in "regedit". Guess they can now use it on any machine. Or maybe they put a new hard drive in, and they’re locked out.
  • IP address tracking is used instead of hwid. Legitimate users can’t use a VPN and run into problems if/when they’re assigned a new IP by their service provider.
  • No hwid checks are performed, and the sign in process has nothing to prevent duplicate sign ins. Oops! 20 people now share one username/password combo, and they’re all using your software for free. Maybe you should have a cool down on sign in attempts per account?
  • The program is not obfuscated in any way. Oops! Everyone can see every little mistake you made, and one of them completely undermines your security. An attacker finds the mistake and spends less than 10 minutes patching the instruction. Worse, the important parts of your program are almost completely visible to the world and someone else decides to make a replica of your program available for free.

Really, though, no solution is perfect. Want it to work offline? Great, now you have to store a file somewhere. When a user shares the program, they just have to share that file as well, and everyone can have offline access. Want to avoid hardware id? Now you need a rate limiter on the sign in, or you can give the users a bit more trust. The best solution is a little bit of DRM sprinkled in, just enough to encourage legitimate sales, without encouraging extra piracy. Pirates are inevitable, and yet you still hope to profit off of your hard work. Good luck.