Problem Description
Solution
To encrypt strings or files in MQL4 to protect your settings, you should use the built-in CryptEncode() and CryptDecode() functions. These functions allow you to encrypt data using secure algorithms like AES-256.
Below is a complete, modular script that demonstrates how to:
- Encrypt a String: Convert a plain text string into an encrypted format.
- Decrypt a String: Convert the encrypted data back to plain text.
- Save/Load to File: Save the encrypted binary data directly to a file and read it back.
MQL4 Encryption Implementation
//+------------------------------------------------------------------+
//| EncryptionExample.mq4 |
//| Copyright 2023, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property script_show_inputs
//--- Input Parameters
input string InpKey = "MySecretPassword123"; // Encryption Key
input string InpText = "SensitiveAPIKey_999"; // Text to Encrypt
input string InpFileName = "EncryptedSettings.bin"; // File to save data
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 1. Encrypt the String
uchar src_data[], key_data[], encrypted_data[];
// Convert string to char array (includes the terminating null)
StringToCharArray(InpText, src_data);
StringToCharArray(InpKey, key_data);
// Encrypt using AES-256
int bytes_encoded = CryptEncode(CRYPT_AES256, src_data, key_data, encrypted_data);
if(bytes_encoded <= 0)
{
Print("Error: Encryption failed. Error code: ", GetLastError());
return;
}
Print("--- Encryption Successful ---");
Print("Original: ", InpText);
Print("Encrypted Bytes: ", bytes_encoded);
// Convert to Hex string for display purposes (optional)
string hex_str = ArrayToHex(encrypted_data);
Print("Encrypted Hex: ", hex_str);
//--- 2. Save Encrypted Data to File
if(SaveToFile(InpFileName, encrypted_data))
{
Print("Saved encrypted data to file: ", InpFileName);
}
//--- 3. Read Encrypted Data from File
uchar file_read_data[];
if(ReadFromFile(InpFileName, file_read_data))
{
Print("Read ", ArraySize(file_read_data), " bytes from file.");
//--- 4. Decrypt the Data
uchar decrypted_data[];
int bytes_decoded = CryptDecode(CRYPT_AES256, file_read_data, key_data, decrypted_data);
if(bytes_decoded > 0)
{
string result_text = CharArrayToString(decrypted_data);
Print("--- Decryption Successful ---");
Print("Decrypted Text: ", result_text);
}
else
{
Print("Error: Decryption failed. Check your Key. Error code: ", GetLastError());
}
}
}
//+------------------------------------------------------------------+
//| Helper: Save byte array to binary file |
//+------------------------------------------------------------------+
bool SaveToFile(string filename, uchar &data[])
{
// Open file for writing binary
int handle = FileOpen(filename, FILE_WRITE|FILE_BIN);
if(handle == INVALID_HANDLE)
{
Print("Error opening file for writing: ", filename);
return false;
}
// Write the array
FileWriteArray(handle, data);
FileClose(handle);
return true;
}
//+------------------------------------------------------------------+
//| Helper: Read byte array from binary file |
//+------------------------------------------------------------------+
bool ReadFromFile(string filename, uchar &result[])
{
// Open file for reading binary
int handle = FileOpen(filename, FILE_READ|FILE_BIN);
if(handle == INVALID_HANDLE)
{
Print("Error opening file for reading: ", filename);
return false;
}
// Read the array
FileReadArray(handle, result);
FileClose(handle);
return true;
}
//+------------------------------------------------------------------+
//| Helper: Convert uchar array to Hex String (for display/debug) |
//+------------------------------------------------------------------+
string ArrayToHex(uchar &arr[])
{
string res = "";
for(int i = 0; i < ArraySize(arr); i++)
{
res += StringFormat("%.2X", arr[i]);
}
return res;
}
Key Concepts Explained
-
CryptEncode&CryptDecode:- These are the core functions.
- Method: We used
CRYPT_AES256. This is a symmetric encryption standard, meaning the same key is used for both encryption and decryption. - Data Types: These functions work with
uchar(unsigned char) arrays, not strings directly.
-
StringToCharArray:- Before encryption, strings must be converted to byte arrays.
- This function copies the string characters into a
uchar[]. It automatically includes the null terminator (\0), which is useful because when you decrypt later,CharArrayToStringwill know exactly where the string ends.
-
File Operations (
FILE_BIN):- When saving encrypted data, you must use the
FILE_BINflag inFileOpen. - Encrypted data is binary, not text. If you try to save it as
FILE_TXTorFILE_CSV, the data will be corrupted because specific bytes (like line breaks or nulls) will be interpreted incorrectly. FileWriteArrayandFileReadArrayallow you to dump the raw encrypted bytes directly to the disk.
- When saving encrypted data, you must use the
-
Security Note:
- The security of this method depends entirely on the Key.
- If you hardcode the key in your EA (Expert Advisor), a determined hacker could decompile the ex4 file and find the key string.
- To improve security, consider constructing the key dynamically (e.g., based on the Account Number) or obfuscating the key string construction logic.
Q&A: MQL4 Encryption
Q: Can I use this to license my EA?
A: Yes. You can encrypt an expiration date or account number string. When the EA runs, it decrypts the string. If the decryption fails (wrong key) or the data doesn't match the current account, the EA stops.
Q: Why does the output look like random characters if I print it?
A: Encrypted data is raw binary bytes. It is not meant to be human-readable text. If you try to Print() the raw encrypted string, it may cut off early (due to null bytes) or show garbage. Always convert to Hex (using the ArrayToHex helper provided above) or Base64 if you need to display it.
Q: Is CRYPT_DES or CRYPT_AES256 better?
A: CRYPT_AES256 is significantly more secure. DES is an older standard that is considered insecure for high-sensitivity data, though it is faster and sufficient for basic obfuscation.
Q: Where are the files saved?
A: Files created by FileOpen are stored in the "File Sandbox" of your terminal. You can find them by going to File -> Open Data Folder, then navigating to MQL4 -> Files.