Partial Serial Number Verification System in Javascript

Davide Barranca —  — 10 Comments

Back in 2007, developer Brandon Staggs wrote a brilliant article about software licensing, showing how to implement what he calls a Partial Serial Number Verification System using the Delphi language.
Apparently the remarkable technique first appeared around 2003 in a set of slides by Chris Thornton, developer of the ClipMate software.

Years have passed, cryptography is more affordable, yet I would say that this approach to the Software Licensing problem is still valid in some businesses – besides the fact it’s fascinatingly clever.

In a nutshell, Staggs shows how to build a serial number (seed, keys, checksum), which keys verification in the final product is partial – so that a cracker would hardly be able to build a long lasting keygen.

I’ve ported the code to Javascript (originally written in Delphi). Two caveats:

  1. My understanding of Delphi is very limited: in fact I’ve never seen any Delphi code before, the port is entirely based on searching the Language Reference and a bit of common sense.
  2. As a translation to a different language, mine is a pretty literal one. I’ve also avoided ES5 / ES6 features on purpose: I wanted the code to run on the Photoshop ExtendScript interpreter (which is very unfortunately stuck to ES3).

As follows, Brandon Staggs introduction quoted with his permission from the original article – which I highly recommend you to read since he discusses the concept and details his code.
Then you can find my Javascript version (frankly, I thought it would have been slightly easier to write).
Eventually, a link section with some reference URLs that I visited while studying the code and that might help you as well.

Brandon Staggs original Introduction

Most micro-ISVs [Independent Software Vendors] use a serial number/registration code system to allow end users to unlock or activate their purchase.  The problem most of us have run into is that a few days or weeks after our software is released, someone has developed a keygen, a crack, or has leaked a serial number across the internet.

There are several possible solutions to this problem. You could license a system like Armadillo/Software Passport or ASProtect, or you could distribute a separate full version as a download for your paying customers. Each option has advantages and disadvantages. What I am going to show you is a way to keep “rolling your own” license key system while making working cracks harder for crackers to produce, and working keygens a thing of the past.

Aside: If you think it’s crazy to post this publicly where crackers can see it, don’t worry about that. I’m not posting anything they haven’t seen before. The entire point of partial key verification is that your code never includes enough information to reverse engineer a key generation algorithm. Also, I offer no warranty of any kind — this is for your information only! Now, on with things.

Our license key system must meet some basic requirements.

  1. License keys must be easy enough to type in.
  2. We must be able to blacklist (revoke) a license key in the case of chargebacks or purchases with stolen credit cards.
  3. No “phoning home” to test keys.  Although this practice is becoming more and more prevalent, I still do not appreciate it as a user, so will not ask my users to put up with it.
  4. It should not be possible for a cracker to disassemble our released application and produce a working “keygen” from it. This means that our application will not fully test a key for verification. Only some of the key is to be tested. Further, each release of the application should test a different portion of the key, so that a phony key based on an earlier release will not work on a later release of our software.
  5. Important: it should not be possible for a legitimate user to accidentally type in an invalid key that will appear to work but fail on a future version due to a typographical error.

The solution is called a Partial Key Verification System because your software never tests the full key. Since your application does not include the code to test every portion of the key, it is impossible for a cracker to build a working valid key generator just by disassembling your executable code.

This system is not a way to prevent cracks entirely. It will still be possible for a cracker to edit your executable to jump over verification code. But such cracks only work on one specific release, and I’ll suggest a couple of tricks to make their job harder to complete successfully. […]
[Quoted with permission]

Javascript port of the original Delphi code

Reference Links

Hope this helps!
Thanks for reading and if you feel dandy there’s always that yellow “Donate” button in the top-left corner 🙂


I would like to thank Brandon Staggs for the kind permission of quoting his original article – pay a visit to his blog and the StudyLamp Software LLC website.


Print Friendly, PDF & Email

10 responses to Partial Serial Number Verification System in Javascript

  1. Evgeny Trefilov July 20, 2015 at 11:55 PM

    As I see, almost everybody keeps extension code as .jsx without obfuscating it as .jsxbin
    also usually all checks will be performed in ext.js

    now, does it take a lot of hacking to go to
    ~/Library/Application\ Support/Adobe/CEP/extensions/

    and modify extension to one’s needs, removing serial checks in particular?

    • Hi Evgeny,
      not obfuscating to JSXBIN is IMHO a big mistake (especially if you want to perform privacy critical tasks) – as you said, someone doesn’t bother to, others do.
      I’m currently prototyping a Licensing system based (also) on RSA cryptography (signing/verification), and everything happens in the JSX: all my panels’ core is Photoshop image processing routines, and it’s easy to stop functionality in there, if licensing fails. E.g. while the extension initialises vars in JSX it also performs licensing check: if this step is bypassed, the initialisation is broken and subsequently (even if the Panel itself appears functional) you can click buttons but they won’t work as expected.
      The big pain in the neck is that, being forced to work in ExtendScript, we’re limited to ECMAScript 3 – it would be easier if the ExtendScript engine were ES5/6 compliant, but I’ve no any hope this will ever happen (and if you think about it, it’s a cul-de-sac as French would put it: a dead end). Panels, with node.js and all the rest, could potentially be more powerful, but due to the very nature of HTML/JS they’re not suitable to host such licensing code – unless you host/dispatch all the panel’s content server side, authenticating every time (but this would require constant internet connection)

  2. Hi Davide,

    Fist of all, thanks for the outstanding resource(s) you are offering here at your site, it’s a treasure trove of pure nuggets of coding goodness. Thanks for sharing your knowledge (which seems to be off the charts 😉

    // ——————————————————————————–
    “I’m currently prototyping a Licensing system based (also) on RSA cryptography (signing/verification), and everything happens in the JSX”
    // ——————————————————————————–

    Are you planing on sharing your findings/approach further with an additional write up for licensing JSX? Or releasing a framework perhaps? 😉 I have been searching for sometime on an approach to license JSX script files and came across this post during my searching. The topic seems to be an extremely rare/scarce topic except for those who figured it out and are doing it behind the scenes already. 😉

    Any further information/details on the topic would be warmly welcomed.

    Keep up the great work. Thanks so much!


    • Hi LL, thanks for the kind words! Frankly I don’t feel particularly skilled nor expert as a coder (especially when HTML Panels are involved – the average front-end developer knows much more than me I’d say) but I’ve already found myself in a number of “typical issues” and more or less I know how to keep the head above water. The rest (as my family well knows) is constant mumbling & cursing & general frustration feelings 🙂

      As for the Licensing System: you’re right, resources are almost non-existent. On one side developers who have implemented it keep the secret for obvious reasons, on the other side it’s a topic on which you can easily end up with wasting a huge amount of time (time you could spend building other products, which have a direct impact over your incomes; conversely, a licensing system does not imply any sort of pirate-conversion-rate). It’s an interesting topic (philosophically I’d say) which I’d like to blogpost about sooner or later.

      Anyway, to answer your question: my plan is to eventually release the licensing system as a framework for Panels and Scripts. But I need to find a way to monetize all the time I’ve spent on it (not that I want to get rich & famous – just repay my own freelance time, which is fair towards my business “me”) and I still have to understand how. Videotut are extremely time consuming, an ebook possibly? Which ironically is the most piratable thing in the whole digital world.

  3. Hi Davide,

    I submitted a response, then resubmitted it, and it never showed up? Hope this finds you well.


  4. Hi Davide

    I tried your code above, and I think I have found a bug here
    int the PKV_checkKey function:

    /* test against blacklist */
    var bl = BL.length
    if (bl) {
    for (var i = 0; i -1 ) {
    result = KEY_BLACKLISTED;
    return result;

    line: k.indexOf(BL[i].toUpperCase()) > -1 , the k should be key, ortherwise the code would not working properly.

    thanks for you code!

  5. Rene Bartholomay August 21, 2015 at 10:02 AM

    Very nice!

    Is there a way to build valid Keys if the seed is a smaller value like 1234 or 272027552?
    If i try this i can´t build valid keys…

    Bye, René

  6. David R Hartman November 4, 2016 at 3:47 PM

    I noticed that some combinations of 8-bit integers in generating the keyByte would result in a number <= 16 (0…F) and this would cause the outputted key to have an incorrect length of characters. I've added the following line after the 255 mask:

    if(result <= 16) {result = result | 0x10;} // mask values <= 16

    to catch any single character outputs. This is just a quick patch before I can look more into how to fix this with the bitwise operations unless someone here has more insight into it


Leave a Reply

Text formatting is available via select .

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">