Copy Protection questions


#1

Hi all:

I’m working on a copy protection function for my upcoming plugin. Here’s a quick summary of what I have so far:

  • When the plugin is instantiated, it calls my copy protection function (this will probably be inlined in my release code, to make things slightly harder to crack).
  • The copy protection function looks for an XML nitialization file, which is created by the installer for the plugin, and put in a known place. For OSX, I am using ~/Library/Application Support/[companyName]/[pluginName] for the directory. Not sure about the best path for Windows, as this has changed for Windows 7.
  • The XML initialization file is parsed to see if there is a valid serial number/ keyfile there.
    • if the serial number/ keyfile is present and validates, then the plugin enters into the active mode
    • if the serial number / keyfile isn’t there, a FileChooser window is called (or FileChooserDialogBox), asking the user to provide the path to a file that contains the serial number / keyfile.
    • if the serial number isn’t present in the new file, or if the user declines to provide a path to the file, or if the serial number doesn’t validate, the plugin enters demo mode.
    • if the serial number in the new file is validated, the program enters active mode, the serial number is put into the XmlElement, and the XmlElement overwrites the original XML file.

My questions:

  • Where is the best place to call my copy protection function from? Right now, it is called when the plugin is instantiated, but this happens when the host starts up. Is there a location that would be better? Is there an AudioProcessor “initialization” function that I should call the code from, rather than instantiation?
  • Is it OK to store the serial number / keyfile as an XML attribute, or should it be an element?
  • Any advantages to FileChooserDialogBox over FIleChooser?
  • What type of encryption would be best?
  • Any other tips you can put in a public forum? (feel free to PM me if you have private tips you feel like sharing)

Thanks,

Sean Costello


#2

I’d separate the two aspects:

  1. the audio processor should attempt to validate itself upon instantiation, and silently enter demo mode if it can’t find the informations that activate the plug-in. No user interaction required.

  2. Only when the plug-in editor (i.e. the user interface) is shown, if the plug-in is not active, the nag screen where to choose an appropriate key file should appear.

This way, you will probably get away with most hosts’ scanning procedures without prompting the user that just wants to demo your plug-in with tons of windows. It can get pretty annoying. He will be prompted for that only when he actually instantiantes and sees the plug-in interface.

One more suggestion regarding point 2: the easiest way to do that, is to show the nag screen in the editor’s constructor, but this means that you will be showing the nag screen while the main plug-in interface is not on the screen yet… this may me a little confusing for the user, that’s why I advise you to trigger it asynchronously, with a ActionBroadcaster/ActionListener pair, triggered by the editor for itself.


#3

Good advice there. Nothing more annoying than nag screens when the host is booting up.


#4

Although it sounds overkill, I’d suggesting adding a secondary level of protection: just the same stuff as usual, but dont call any of the functions until a counter of some kind (preferably one that increments by one every time the plugin is initialised, for example) reaches a set value.

This doesnt need to be incredibly arcane - most plugins have some external files (library/bank) so the counter can be kept there, or in registry or whathaveyou. come up with some clever incrementing number system so its not just i++;

Release teams usually just crack the software so that the full version works. Testing is minimal, because it isnt fun, and the race is to create a stable release of the latest plugin as soon as possible.

A few big big sellers use this trick. Games people use a variant which is to release a free ‘update’ about 2 weeks after the game is released. This update requires validation to a central server of a serial key, and by this mean people with cloned serials cannot as easily get the update. If the updated version is widely cracked, a new version is released, in a straight forward tit-for-tat race. This only really happens with mega big selling software.


#5

Yeah, that is the EXACT behavior that my plugin currently has. I’ll be implementing yfede’s advice.

Sean


#6

I am working on RSA encryption / decryption for a keyfile. The encryption will be performed on a string that contains some user information. However, what else should it contain? I presume that there needs to be something that is parsed to perform the check to ensure that it is a valid string. A few ideas:

  • Some constant string, that needs to be the first in line
  • Checking the user information in the encrypted string with other information in the keyfile. For example, make sure that the encrpyted user first and last names are the same as the first and last names listed elsewhere in the keyfile.

Any suggestions are greatly appreciated, as always. If you want to PM me about such stuff, feel free.

Sean Costello


#7

Hi, I found this thread very useful when I was working on this kind of thing: http://www.rawmaterialsoftware.com/viewtopic.php?f=2&t=1245&start=0

Our plugin’s copy protection is based on a challenge response system so we embed a unique machine id in our keyfiles along with the rest of the user data (at the moment we store the name, company, product id, major version number and serial number). Then we encrypt the lot and just make sure the serial number is a valid serial and the machine id matches when we examine the keyfile.

If you want to avoid challenge/response you could calculate a checksum from all the data you’re going to encrypt before you encrypt it. Then store that in the keyfile separate to the encrypted data. Then when you decrypt you can compare with the decrypted data with the stored checksum to make sure you’re looking at a valid keyfile.


#8

OK, I’ve changed tack slightly. I now plan on having a dedicated demo, hardwired at compilation time. The paying customers will have a private download for the full version, and will be sent a serial number to authorize things.

The desired behavior is that the user is given a prompt to authorize the plugin when the plugin is instantiated in the DAW. If the authorization fails, the plugin won’t work, but in a graceful way that doesn’t crash the DAW.

So…any suggestions on graceful ways of keeping a plugin from working without crashing the DAW? I essentially want it to close itself down, or delete itself, or whatever you want to call the behavior. Sorry I don’t know the proper phrasing - I’ve been staying up way too late this week…

EDIT: Should I be looking at suspendProcessing and isSuspended() in AudioProcessor?

Thanks,

Sean Costello


#9

I think that simply bypassing the plug-in (i.e. it will pass it’s input unprocessed to the output) with a big “UNAUTHORIZED” sign is clear enough…


#10

That would work just fine. Thanks!

Sean Costello