당사 팬 페이지에 가입하십시오
- 조회수:
- 41229
- 평가:
- 게시됨:
- 2016.05.25 13:11
-
이 코드를 기반으로 한 로봇이나 지표가 필요하신가요? 프리랜스로 주문하세요 프리랜스로 이동
Several methods of protecting your code have been proposed over the past, but were either too simple (less secure), required re-compilation of your code for each new customer (ok if you only plan on having a dozen or so customers) or far too complicated involving a remote host to validate the client terminal.
Here I propose a simple password verification scheme which uses MT4's built in security engine providing DES/ECB encryption and does not require code re-compilation for each new customer.
Having worked on several high profile Canadian smart card initiatives, I became quite familiar with the various security schemes used by financial institutions and card issuers. The first question you have to ask yourself is "What's at risk?". A risk assessment is always done when starting a project with these guys. If the answer is "Millions and millions of dollars", then this security scheme is not for you.
If, on the other hand, your answer is "A month or two of coding if somebody spends about a year hacking my security scheme", then this solution is for you. The single DES key used in this encryption scheme will provide more than adequate security for your code and will not require code re-compilation for new clients.
I have provided two source files for your convenience. The first one "Password_Check" is what you will add to your indicator or expert advisor. It will verify the password entered by the user in the input parameter "Password" and if the password is incorrect (or if the user is offline) it will display a user friendly message, remove the expert (if that's what's running) and return a INIT_FAILED status.
The second file, "Password_Generate", is used to enter the client's name and account number you want to protect. It will display the password generated so you can provide this to your clients. Obviously, you don't want to include this code in your final product! :)
So let's get started...
First, we need to define an input string to your indicator or Expert Advisor:
//--- input parameters extern string Password;
Next, we add code in the init() function to check the password and display a message if the password is incorrect, if the user is offline or the user simply didn't enter a password.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int init() { string client = NULL; // Make sure the client is online in order to get his client name and account number if(IsConnected()) client = AccountInfoString(ACCOUNT_NAME) + " / " + DoubleToStr(AccountInfoInteger(ACCOUNT_LOGIN), 0); // Check client's password if(!Password_Check(client)) { if(StringLen(Password) != 0) MessageBox("Unable to verify client and account number!" + (IsConnected() ? "\nPlease verify you have the correct password." : "\n\nYou need to be online for verification."), (IsConnected() ? "Invalid Password!" : "Offline!"), MB_OK | MB_ICONSTOP); else MessageBox("Unregistered software.\n\nPlease contact software vendor to obtain\nyour personal activation password." + (StringLen(client) == 0 ? "" : "\n\nYour registration information is:\n\n'"+client+"'"), "Unregistered", MB_OK | MB_ICONSTOP); // Invalid password or user is offline. Remove expert and exit with error ExpertRemove(); return(INIT_FAILED); } // All good... return(INIT_SUCCEEDED); }
Now come the meat... We need to encode the client name and account number with our DES key, encode the result into BASE64 and compare with the password entered. If the result matches, you have a happy customer. If they don't, you have a hacker trying to crack your DES key. Given that the expert advisor will unload itself each time a wrong password is entered, you'll probably have time to retire in Bora Bora before they succeed!
//+------------------------------------------------------------------+ //| Validate client's password //+------------------------------------------------------------------+ bool Password_Check(string client) { string MasterKey; uchar dst[], src[], key[]; // Define your encryption key here. Must be 7 characters for DES/ECB encryption // Make your password difficult to figure out. You last name is not a good idea! // Something like "wLdU&$z" would be good. For now, we'll use a simple one... MasterKey = "NotDemo"; // Convert MasterKey to character array StringToCharArray(MasterKey, key); // Make sure client string is not null if(StringLen(client) == 0) return(false); // Encrypt the client using DES key StringToCharArray(client, src); CryptEncode(CRYPT_DES, src, key, dst); // Clear key and encode to BASE64 ArrayInitialize(key, 0x00); CryptEncode(CRYPT_BASE64, dst, key, src); // Compare password and return result return(CharArrayToString(src) == Password); }
That's it! We can now validate the client name (as taken from MetaTrader 4's client account name) plus the client account number (also taken from MetaTrader 4).
If your licensing policy is to allow multiple accounts for a single client, then you only need to remove the account number from the 'client' string, as follows:
// Make sure the client is online in order to get the client name if(IsConnected()) client = AccountInfoString(ACCOUNT_NAME);
Of course you can do a mix and match with "Broker Name", "Account Name" and "Account Login" the way you see fit. Just remember that the longer the 'client' variable is, the longer the encrypted password will be.
Next, let's take a look at the "Password_Generate" code. What we want to do is the same as the "Password_Check" but instead of entering a password into the EA, we want to enter the client name (or combination of Broker Name, Account Name and Account Login you choose) to be encrypted and then display the generated password. This is what you'll give to your clients when they purchase your kick-ass indicator and/or Expert Advisor.
Again, in your init() function you'll add the following code.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int init() { string Password = NULL; // Make sure the Client input is not empty if(StringLen(Client) != 0) { // Generate a client password Password = Password_Generate(Client); // Print the generated password (makes it easy to cut and paste) Print("Client: '"+Client+"' Password: "+Password); // Display the password generated for client MessageBox("Password generated for client / account\n\n'"+Client+"' is:\n"+Password, "Password Generator", MB_OK | MB_ICONINFORMATION); } else MessageBox("You must specify a client / account number!", "Password Generator", MB_OK | MB_ICONSTOP); // All good. Remove expert. ExpertRemove(); return(INIT_SUCCEEDED); }
Now we do a slight modification to our "Password_Check()" function to return a string of the encoded password. Remember to use the same password in BOTH the Password_Check() function and Password_Generate() function. You can image what will happen if you don't!
//+------------------------------------------------------------------+ //| Encrypt client information and return the password //+------------------------------------------------------------------+ string Password_Generate(string client) { string MasterKey; uchar dst[], src[], key[]; // Define your encryption key here. Must be 7 characters for DES/ECB encryption // IT MUST BE THE SAME PASSWORD AS DEFINE IN THE "Password_Check()" function! // Make your password difficult to figure out. You last name is not a good idea! // Something like "wLdU&$z" would be good. For now, we'll use a simple one... MasterKey = "NotDemo"; // Convert MasterKey to character array StringToCharArray(MasterKey, key); // Encrypt the client using DES key StringToCharArray(client, src); CryptEncode(CRYPT_DES, src, key, dst); // Clear key and encode to BASE64 ArrayInitialize(key, 0x00); CryptEncode(CRYPT_BASE64, dst, key, src); // Return encypted password return(CharArrayToString(src)); }
That's it, that's all. You enter the information provided to you by your client and you send them the password by email or whatever other means you choose. Of course, the beauty of this is that you can do this from your living room in Bora Bora!
As stated before, this security scheme does not require you re-compile your code for each new customer or code a server side validation host while providing pretty good security for your hard work creating that kick-ass indicator / Expert Advisor of yours!
Cheers!
-Claude.
![Tipu Renko Live](https://c.mql5.com/i/code/indicator.png)
Tipu Renko Live is a modified version of Renko Charts that can be plotted on a normal time frame.
![3DaysHiLo](https://c.mql5.com/i/code/indicator.png)
Simple indicator which displays High and Low 3 days ago.
![Swing Point Highs and Lows](https://c.mql5.com/i/code/indicator.png)
This indicator helps to determine swing point highs and swing point lows.
![Trading Volume Indicator](https://c.mql5.com/i/code/indicator.png)
Trading Volume indicator shows the volume of buying and selling trades on the current bar or on average of specific number of last bars as you want . Both volumes are shown simultaneously with green and red colors for buying and selling trading volumes respectively.