Simple copy protection done right :)



  • @Lindon dont worry - answered it myself - no.



  • will try to find how add user name (with a print as "registered to: "name of user")

    it could be good No ?



  • How about a bundle products? For example a bundle that consists of 20 different plugins.

    Any suggestions for preventing the user from entering serials of the 20 products one by one?



  • Store the entered serial one parent directory up. In HISE this will be superweird but the compiled version will end up in your Company folder (you might need to add a bundle ID to the JSON you store on disk)



  • Ok I see, I set 2 folders up from the root folder:

    "../../RegistrationInfo.js"
    


  • Yes, but choose a filename that won't conflict with other bundles you might offer 🙂



  • @Christoph-Hart Good idea 😉



  • @Lindon said in Simple copy protection done right 🙂:

    Actually I dont store all the numbers in the interface - I use an formula to calc if the entered numbers are valid or not...Kontakt is so much easier to hack the (KSP) code so including the numbers was never really an option. HISE not so much of a problem. One more win for HISE...

    Is there any progress for this serial decoder formula stuff?



  • No and there never will be. As soon as you use a publicly available "formula" to create these serials, your entire copy protection scheme is pointless.

    Use the tools and come up with a random processing and combination of the things to create valid serials. Then tell nobody how you did it 🙂



  • @Christoph-Hart

    No and there never will be. As soon as you use a publicly available "formula" to create these serials, your entire copy protection scheme is pointless

    I came up with such a scheme for Kontakt. The formula can be made public as it relies on each instrument containing a unique number in its script that is used to encode/decode the serials. I'll post the script when I'm at my computer.



  • @Christoph-Hart Yes of course the formula shouldn't be shared. And I think without formula method is useful too.



  • @Christoph-Hart I mean how can we approach this encoding and decoding process..etc. I've found this could it be useful? : https://gist.github.com/ubergesundheit/5626679



  • Yeah, good luck pasting throw new RuntimeException("VIN number must be 17 characters"); into HISE 🙂



  • @Christoph-Hart ok, we can't use that 🙂



  • @orange said in Simple copy protection done right 🙂:

    @Christoph-Hart Yes of course the formula shouldn't be shared. And I think without formula method is useful too.

    If the only way your lock is secure is to not tell people how the lock works then your lock is not secure.

    The code I'm posting here is in KSP. I'll leave it to someone who wants to use it to convert it to HISEScript and integrate it with Christoph's system.

    This function generates a serial number based on values in the %app_number array. The app number an 8 element array. Each plugin should have a unique app number. You can think of the app_number like a password, if you know the app number then you can encode/decode a valid serial number.

    function sl.generate_serial(serial)
    {Generate a random serial number, use %app_number array to perform calculations}
    
        declare $i
        declare $random_value
    
        for $i := 0 to (num_elements(serial))-1 {serial is 8 digits, we create 2 at a time so only need to loop 4 times}
    
            $random_value := random(0,999) {Generate a Random Number between 0 and 999}
    
            if ($random_value > %app_number[$i]) {If the random number is greater than the %app_number number}
                serial[$i] := (($random_value - %app_number[$i])*2) mod 1000 {The serial[$i] is the Random Value - the %app_number Number}
            else
                serial[$i] := ((%app_number[$i] - $random_value)*2) mod 1000
            end if
    
            serial[$i+1] := $random_value {Store the random value in the second half of the serial}
            inc($i)
    
        end for
    
    end function
    

    I made a windows exe (written in C#) that generates thousands of serials based on your app number and it uses the above formula. If anyone finds this code useful then I can share the exe too.

    This function validates a serial provided by the user against the app_number

    {/**
    * This is the reverse of the serial key generating function.
    */}
    function sl.validate_serial(serial, app_number) -> return
    
        declare $i
        declare $n
        declare %new_serial[8] {Same size as serial[], we store the values we get as we rebuild the serial for comparison}
        
        for $i := 0 to num_elements(serial)-1
    
            if (serial[$i+1] > app_number[$i])
                new_serial[$i] := ((serial[$i+1] - app_number[$i]) * 2) mod 1000
            else
                new_serial[$i] := ((app_number[$i] - serial[$i+1]) * 2) mod 1000
            end if
    
            new_serial[$i+1] := serial[$i+1]
            inc($i) {We want to skip in 2's}
    
        end for
    
        {Check if the serial matches the New Serial}
        if array_equal(serial, new_serial)
            return := 1
        else
            return := 0
        end if
    
    end function
    

    I made a function to fill the app_number array and display it. This was just to save me doing it manually but you can do it manually if you prefer

    {/**
    * Randomly generates an app number and stores it in the app_number array. The app number is then displayed in the message bar.
    * This function should not be left in the script. It should be called once, the app number should be noted and the instrument saved to preserve the app number
    * The function call should then be removed or commented out before recompiling the script. The app number can be replaced by recalling the function and saving.
    */}
    function sl.generate_app_number()
        
        declare $i
    
        for $i := 0 to 7
            %app_number[$i] := random(1, 999)
        end for
    
        message(%app_number[0] & ' - ' & %app_number[1] & ' - ' & %app_number[2] & ' - ' & %app_number[3] & ' - ' & %app_number[4] & ' - ' & %app_number[5]...
         & ' - ' & %app_number[6] & ' - ' & %app_number[7])    
    
    end function
    


  • @d-healey Outstanding! Thank you!



  • @Christoph-Hart I am trying to check the serial input on 2 different serial lists. There are two serial lists;

    • Bundle serials (stores and checks the file in "../Individual_RegistrationInfo.js" )
    • Individual serials (stores and checks the file in "../Bundle_RegistrationInfo.js" )

    It works on bundle serial list checking but not works on Individual serial list 😞 What is the thing that I missed?

    namespace Authorisation
    {
        const var SerialInput = Content.getComponent("SerialInput");
        const var Description = Content.getComponent("Description");
        const var SerialStateLabel = Content.getComponent("SerialStateLabel");
        const var AuthorisationDialogue = Content.getComponent("AuthorisationDialogue");
    
        
        
        inline function onSubmitButtonControl(component, value)
        {
          if(!value) 
                return;
        
            local v = SerialInput.getValue();
            Console.print(v);
    	
    // Checks if it's in the Individual Serial sList
            if(Individual_serials.Data.contains(v))
            {
                Console.print("Serial number found");
            
                local data = 
                {
                    "Serial": v
                };
            
    // Saves as Individual_RegistrationInfo.js 
                Engine.dumpAsJSON(data, "../Individual_RegistrationInfo.js");
                
                setValidLicense(true);
            }
            
      
     // Checks if it's in the Bundle Serial sList
        if(Bundle_serials.Data.contains(v))
            {
                Console.print("Serial number found");
            
                local data = 
                {
                    "Serial": v
                };
    
     // Saves as Bundle_RegistrationInfo.js 
                Engine.dumpAsJSON(data, "../Bundle_RegistrationInfo.js");
                
                setValidLicense(true);
            }      
    
            
            else
            {
                Console.print("Invalid serial number");
                Description.set("text", "INVALID KEY THAT DOES NOT MATCH WITH YOUR LICENSE");
                
                setValidLicense(false);
            }
        };
    
        Content.getComponent("SubmitButton").setControlCallback(onSubmitButtonControl);
    
    
    
        inline function setValidLicense(isValid)
        {
                
            if(isValid)
            {
                // My action
            }
            else
            {
                // My action
            }
        }
    
        inline function checkOnLoad()
        {
            SerialInput.set("text", "");
            
    // Load the serial from the stored files
    
            local pData_Individual = Engine.loadFromJSON("../Individual_RegistrationInfo.js");
            local pData_Bundle = Engine.loadFromJSON("../Bundle_RegistrationInfo.js");
            
            Console.print("Checking serial");
        
    // Individual serials
            if(pData_Individual)    
            {
                local v = pData_Individual.Serial;
                Console.print("Restored serial: " + v);
            
               if(Individual_serials.Data.contains(v))
                {
                    setValidLicense(true);
                    return;
                }
        }
    
    // Bundle serials    
          if(pData_Bundle)    
            {
                local v = pData_Bundle.Serial;
                Console.print("Restored serial: " + v);
            
               if(Bundle_serials.Data.contains(v))
                {
                    setValidLicense(true);
                    return;
                }      
        }
    
          setValidLicense(false);
      }    
        
    // Call this on startup
        checkOnLoad();
    
    }
    


  • Basics:

    if(x)
    {
        // Will be executed if x is true
    }
    if(y)
    {
       // will be executed if y is true
    }
    else
    {
       // will be executed if y is false 
       // no matter what x is
    }
    

    Solution:

    else if(y)
    

    Protipp: y is Bundle_serials.Data.contains(v) 🙂



  • @staiff I already did it

    reg.png



  • This post is deleted!

Log in to reply
 

8
Online

503
Users

1.8k
Topics

13.7k
Posts