Libraries: Licensing class and script with 64bit Encryption (more Reliable)

 

Licensing class and script with 64bit Encryption (more Reliable):

This class loads a licensing file by reading 64bit encrypted account data from a license file into an account array for the purpose of licensing. The Class is initialised with a Filename, a Master Key and whether the file needs to be saved in the common folders or not.

Author: Jason Kisogloo

 


I am very sorry to tell you this, but your code does not even encrypt the data. All it does is recode the data to base64....


Maybe it would help to read the documentation.

Here you go:

https://www.mql5.com/en/docs/constants/namedconstants/otherconstants

It states clearly: 

CRYPT_BASE64

BASE64


How is this related to security?

https://de.wikipedia.org/wiki/Base64


Please correct your code. - Others might find your code useful and trust your abilities, but then... well...


I would suggest to do following:


Create:

1. Encrypt using AES256

2. Recode to Base64

3. write to file


Check:

1. Read from file

2. Recode from Base64

3. Decrypt


Leaving it the way it is, is simply irresponsible.

Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Other Constants
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Other Constants
  • www.mql5.com
Other Constants - Named Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

I suppose you had trouble with the encryptet data because you were using a string to store the data.


Strings per definition have a so called stop-character. This is used to programmatically determine the end of the string.

Since encrypting data will generate data in the full range of 0 to 255 per character/byte, you will end up with some "stirngs" having the "end-of-string" character somewhere in the middle of your data.


Therefore you must use a char-array and handle this. Do not transform the data into a string as long as it is not base64 encoded. - Thats why you can encode data to base64. This way you can store any data within the range of legal characters for a string.

This is also the reason why your first versio ndid not work "reliable".

 

Another addendum. 

DES encryption is only... cannnot find words - Jesus, this is... 

Stop using such old stuff for security.


BTW: when coding secure applications or functions, you would always overwrite the memory you have been using, so the data is not shadowed in memory... - If you call the function twice, you would see the data from the former call before you clear the memory to NULL.

There are quite some other aspects, you need to consider when working with secure code. 

 
Dominik Egert:

Another addendum. 

DES encryption is only... cannnot find words - Jesus, this is... 

Stop using such old stuff for security.


BTW: when coding secure applications or functions, you would always overwrite the memory you have been using, so the data is not shadowed in memory... - If you call the function twice, you would see the data from the former call before you clear the memory to NULL.

There are quite some other aspects, you need to consider when working with secure code. 

This is a simple method I created based on MQL Documentation on how to encrypt data to a file... I am new to encoding and decoding encrypted data, i tried 256 bit AES but this did not decode consistently... if you have a better encryption code... please share it...


I used character array and made sure no end of line characters are in place... if you can improve on the code please share...

 

64bit ENCODING is one thing. 

64bit ENCRYPTION is another thing. 


Wikipedia and Google can help you understand the difference between them. They are completely different things.

 

Encryption is the process of securely encoding data in such a way that only authorized users with a key or password (done) can decrypt the data to reveal the original. Encoding data is used only when talking about data that is not securely encoded. ... An example of encryption is: AES 256


So googled it and used a key to encrypt... that nobody would know...so not sure why you guys saying this is encoded not encrypted?

 
Jason Kisogloo #:

Encryption is the process of securely encoding data in such a way that only authorized users with a key or password (done) can decrypt the data to reveal the original. Encoding data is used only when talking about data that is not securely encoded. ... An example of encryption is: AES 256


So googled it and used a key to encrypt... that nobody would know...so not sure why you guys saying this is encoded not encrypted?

This topic is still open, and here is your proof of why your code is encoding, not encrypting the data.

//+------------------------------------------------------------------+
//|    Decode a String from 256bit Encryption                        |
//+------------------------------------------------------------------+
string  CLicence::m_Decode(string m_String)
   {
    ResetLastError();
    uchar m_src[],m_dst[];

    StringToCharArray(m_String, m_src, 0, StringLen(m_String));

    string m_Decoded = "";
    int m_result = CryptDecode(CRYPT_BASE64, m_src, m_hashkey, m_dst);
    if(m_result)
       {
        m_Decoded=CharArrayToString(m_dst);
        StringReplace(m_Decoded,"Endof","");
       }
    else
       {
        m_ErrorTxt = "Failed to Decrypt: Err "+(string)GetLastError();
        Alert(m_ErrorTxt);
       }

    return m_Decoded;
   };

//+------------------------------------------------------------------+
//|        Creating the Encrypted Hash Key                           |
//+------------------------------------------------------------------+
bool CLicence::m_GetHashKey()
   {
    uchar m_src[],m_dst[],m_hkey[],m_mkey[];


    ArrayResize(m_hkey,32);
    for(int i=0; i<32; i++)
        m_hkey[i]=uchar((i*17)%59);

    StringToCharArray(m_key,m_mkey, 0, StringLen(m_key));

    ResetLastError();
    if(!CryptEncode(CRYPT_DES, m_hkey, m_mkey, m_hashkey))
       {
        m_ErrorTxt = "Failed to Create Hashkey: "+(string)GetLastError();
        Print(m_ErrorTxt);
        return false;
       };
    return true;
   }

This is from your code, and event though you are creating some "secret key"

uchar((i*17)%59)

which is not secret, you apply it to a functiion call ,that does not respect or better said, ignores the input, because you told it to CRYPT_ENCODE <- by applying CRYPT_BASE64 here:


    int m_result = CryptDecode(CRYPT_BASE64, m_src, m_hashkey, m_dst);


which will only encode the input m_src into BASE64, without applying the content of m_hashkey.

So the content of your file is ENCODED, not ENCRYPTED.


I regret to see 2300 views and 2.5 stars on that code, which is promissing something, that it actually is not doing.

 
Dominik Christian Egert #:

This topic is still open, and here is your proof of why your code is encoding, not encrypting the data.

This is from your code, and event though you are creating some "secret key"

which is not secret, you apply it to a functiion call ,that does not respect or better said, ignores the input, because you told it to CRYPT_ENCODE <- by applying CRYPT_BASE64 here:



which will only encode the input m_src into BASE64, without applying the content of m_hashkey.

So the content of your file is ENCODED, not ENCRYPTED.


I regret to see 2300 views and 2.5 stars on that code, which is promissing something, that it actually is not doing.

thank you for your input, would you be kind enough to share how you would code this?

 
Jason Kisogloo #:

thank you for your input, would you be kind enough to share how you would code this?

I guess it should start with how do you want to handle the protection?

As far as I can see from your code, you would like to create a License for ...

Now let's define, what is needed:

Bind to Account? Bind to User? Bind to Broker?

So what we need is following:

Customer gives us Account, user and broker name. - Or, receive an activation code from the user?

Both would work. Let's say we use an activation key.

Now we encrypt the activation key on our system to send the customer the license key.

Symmetrical Encryption will be used: Both customer and you share the same secret.

The secret cannot be changed. So the coder, who uses your library will have to define once their secret and hardcode it into your library.

This secret will now be used to encrypt the activation key and generate the license key.

This will be passed to the user, the user loads this into the product, the product will now decrypt the license key with the same hardcoded secret. Extract Account number, user name and broker name from that and check against current environment.


How to handle the data:

When generating the activation key, a simple encryption secret could be used, like product name and version.

After encryption, you must encode the uchar array to base64. Then write it to file, log or screen for the user to be able to send it to the developer/coder.

The coder loads the file and first does an base64 decode, then does a decrypt if that uchar array. And uses the simple key, like product name and version for that.

Now he encrypts the same data with the hard coded secret and encodes the uchar Array again in base 64. Store as file, send to user...

Same process on user side now. Decode file content from base 64 to uchar array, decrypt with hard coded password, check against environment.

You could also use an async key pair for encryption/decryption, but that will be much more work.

Advantage would be, only the coder can encrypt a license, but anyone with the public key can decrypt the license. This way, maintenance would be much easier.

This is how I suggest the implementation of your code.

As encryption method, use AES. As encoding use Base64.


 
Dominik Christian Egert #:
I guess it should start with how do you want to handle the protection?

As far as I can see from your code, you would like to create a License for ...

Now let's define, what is needed:

Bind to Account? Bind to User? Bind to Broker?

So what we need is following:

Customer gives us Account, user and broker name. - Or, receive an activation code from the user?

Both would work. Let's say we use an activation key.

Now we encrypt the activation key on our system to send the customer the license key.

Symmetrical Encryption will be used: Both customer and you share the same secret.

The secret cannot be changed. So the coder, who uses your library will have to define once their secret and hardcode it into your library.

This secret will now be used to encrypt the activation key and generate the license key.

This will be passed to the user, the user loads this into the product, the product will now decrypt the license key with the same hardcoded secret. Extract Account number, user name and broker name from that and check against current environment.


How to handle the data:

When generating the activation key, a simple encryption secret could be used, like product name and version.

After encryption, you must encode the uchar array to base64. Then write it to file, log or screen for the user to be able to send it to the developer/coder.

The coder loads the file and first does an base64 decode, then does a decrypt if that uchar array. And uses the simple key, like product name and version for that.

Now he encrypts the same data with the hard coded secret and encodes the uchar Array again in base 64. Store as file, send to user...

Same process on user side now. Decode file content from base 64 to uchar array, decrypt with hard coded password, check against environment.

You could also use an async key pair for encryption/decryption, but that will be much more work.

Advantage would be, only the coder can encrypt a license, but anyone with the public key can decrypt the license. This way, maintenance would be much easier.

This is how I suggest the implementation of your code.

As encryption method, use AES. As encoding use Base64.


It sounds exactly the way i would above functions to work with licence, however the above are just simple functions the keys would be d defined by the coder and what keys would be used to encode and code?