1

I want to store software license keys in a field of my mysql db, but I want to have the license number stored in a scrambled format so that if the db is compromised the license keys won't be usable.

There are 3 scenarios possible with the license key field:

  1. It may be null - some users won't have a license key stored in the db yet.
  2. It may be a 25 digit license, with every 5 characters separated by a hypen: for example: ABCD1-EFGH2-IJKL3-MNOP4-QRST5
  3. It may be a 10 digit license, all of which are numbers and there are no separators: for example: 1234567890

I'd like to scramble the license prior to storing, then when displaying to the user once logged in, run the same scramble function again to unscramble the license.

I think I would need to start by checking the strlen of the license.

  1. If 0, then do nothing. I can check if its null before loading the function.
  2. If 29, then use the hyphen separators to shuffle sections of the license, such as 2nd & 4th and maybe use str_rot13 to change the alpha characters.
  3. If 10, select say the 3rd, 5th, 7th, & 9th characters and change their order. such as 5th with 9th and 3rd with 7th.

I've setup the following:

    function scramble($scramblestr) {

    // check string length
    $length = strlen($scramblestr);

    // if 10 digit license (all numbers)
    if ($length == 10) {
        $1st = substr($scramblestr, 0, 1);
        $2nd = substr($scramblestr, 1, 1);
        $3rd = substr($scramblestr, 2, 1);
        $4th = substr($scramblestr, 3, 1);
        $5th = substr($scramblestr, 4, 1);
        $6th = substr($scramblestr, 5, 1);
        $7th = substr($scramblestr, 6, 1);
        $8th = substr($scramblestr, 7, 1);
        $9th = substr($scramblestr, 8, 1);
        $10th = substr($scramblestr, 9, 1);

        // swap 3rd character with 7th / swap 5th character with 9th
        $scramblestr = $1st . $2nd . $7th . $4th . $9th . $6th . $3rd . $8th . $5th . $10th;

    // if 25 digit license (with hyphen separators)
    } elseif ($length == 29) {
        $scramblestr = array_filter(explode('-', $scramblestr), 'strlen');

        // swap 2nd & 4th sections
        $scramblestr = $scramblestr[0] . "-" . $scramblestr[3] . "-" . $scramblestr[2] . "-" . $scramblestr[1] . "-" . $scramblestr[4];

        // swap alpha characters 13 places in the alphabet
        $scramblestr = str_rot13($scramblestr);

    // if null or if stored incorrectly (for example if the license is not null but contains an invalid number of characters)
    } else {
        $scramblestr = "Unknown";
    }

    return $scramblestr;
}

However, this results in the following server 500 error:

PHP Parse error: syntax error, unexpected '1' (T_LNUMBER), expecting variable (T_VARIABLE) or '$'

This points to the 1st substr reference. However, according to php.net it should be a integer used here to demark length of string.

Any ideas?

Or is there a more efficient way of performing this action? Or does anyone have any alternative methods which may suit?

BottyZ
  • 145
  • 2
  • 10
  • Not quite sure: But a variable can't be (partially) numeric, can it? – CaptainCarl Apr 13 '16 at 14:02
  • Why don't you just hash it ? – Daan Apr 13 '16 at 14:03
  • Please see the answer [here](http://stackoverflow.com/questions/16600708/how-do-you-encrypt-and-decrypt-a-php-string) – LMS94 Apr 13 '16 at 14:04
  • 5
    The problem here is that your variables start with a numeric value; can't do that. Do `$a1st` as opposed to `$1st` etc. Take this as some form of "answer". @BottyZ – Funk Forty Niner Apr 13 '16 at 14:05
  • Also, rot13 is not encryption, it is a joke. :-) – Erwin Moller Apr 13 '16 at 14:06
  • I don't want to hash it, as I want to re-display it for a user to copy once they're logged in and want to re-download their software. Just to be clear, the software license key is not their login password... that's separate and hashed. – BottyZ Apr 13 '16 at 14:06
  • @BottyZ Okay then use a strong encryption don't try to reinvent the wheel. – Daan Apr 13 '16 at 14:07
  • @CaptainCarl Definitely can't start variables with a numeric value, to answer the "not quite sure" ;-) – Funk Forty Niner Apr 13 '16 at 14:08
  • 1
    @BottyZ Here, have a read http://stackoverflow.com/questions/15427476/why-variable-can-not-start-with-a-number and http://stackoverflow.com/questions/342152/why-cant-variable-names-start-with-numbers – Funk Forty Niner Apr 13 '16 at 14:10
  • @Fred & CaptainCarl you were both right, how could I of not realised that... changed the $st to $first and so on... – BottyZ Apr 13 '16 at 14:13
  • @Daan - the problem with encryption is the inability to reverse it when displaying to the user on the webpage. I wanted something that randomises it in a way unique to me and is easy to undo. – BottyZ Apr 13 '16 at 14:15
  • 1
    Might be worth mentioning that if your database is compromised, then your code probably is as well. Meaning whoever got your database can probably decode all of the keys. – DragonYen Apr 13 '16 at 15:02
  • @DragonYen - I agree, I did think about this and discussed it with my employers... The licensed software product we sell isn't massively critical to protect as it is an add on to our actual product, so ease of implementation is preferred. If someone were to compromise the database it might just contain enough abstraction to put them off bothering to find the one script that abstracted it in the first place. If this changes in future I'll obviously update the above. Thanks for your input. – BottyZ Apr 14 '16 at 09:37

3 Answers3

4

"@Fred & CaptainCarl you were both right, how could I of not realised that... changed the $st to $first and so on... – BottyZ"

Submitting as an answer:

The problem here is that your variables start with a numeric value; can't do that. Do something like $a1st as opposed to $1st while starting with a letter.

References on Stack you can have a read:

Community
  • 1
  • 1
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
1

A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'

https://secure.php.net/manual/en/language.variables.basics.php

The naming of your variables, e.g. $1st is invalid.

dbrumann
  • 16,803
  • 2
  • 42
  • 58
0

You can also encrypt the data in the database in MySQL 5.7 or MariaDB 10.1. You can do it with a single field, tables or completed tablespace including logfiles etc.

see: https://mariadb.com/kb/en/mariadb/encryption/

Bernd Buffen
  • 14,525
  • 2
  • 24
  • 39