2026-03-27 09:40:19 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-26 18:15:47 -05:00
|
|
|
//| Encrypt.mqh |
|
|
|
|
|
//| Copyright 2026, MetaQuotes Ltd. |
|
|
|
|
|
//| https://www.mql5.com |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#property copyright "Copyright 2026, MetaQuotes Ltd."
|
|
|
|
|
#property link "https://www.mql5.com"
|
|
|
|
|
#property strict
|
|
|
|
|
|
2026-03-27 09:40:19 -05:00
|
|
|
#ifndef MQLARTICLES_UTILS_ENCRYPT_ENCRYPT_MQH
|
|
|
|
|
#define MQLARTICLES_UTILS_ENCRYPT_ENCRYPT_MQH
|
|
|
|
|
|
2026-03-26 18:15:47 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#include "..\\Basic.mqh"
|
|
|
|
|
#include "..\\RandomSimple.mqh"
|
2026-03-27 09:40:19 -05:00
|
|
|
#include "..\\File\\File.mqh"
|
2026-03-26 18:15:47 -05:00
|
|
|
/*
|
|
|
|
|
2026.03.26 17:37:44.570 Test (EURUSD,H1) CRYPT_BASE64 = 0
|
|
|
|
|
2026.03.26 17:37:44.570 Test (EURUSD,H1) CRYPT_AES128 = 1
|
|
|
|
|
2026.03.26 17:37:44.570 Test (EURUSD,H1) CRYPT_AES256 = 2
|
|
|
|
|
2026.03.26 17:37:44.570 Test (EURUSD,H1) CRYPT_DES = 3
|
|
|
|
|
2026.03.26 17:37:44.570 Test (EURUSD,H1) CRYPT_HASH_SHA1 = 4
|
|
|
|
|
2026.03.26 17:37:44.570 Test (EURUSD,H1) CRYPT_HASH_SHA256 = 5
|
|
|
|
|
2026.03.26 17:37:44.570 Test (EURUSD,H1) CRYPT_HASH_MD5 = 6
|
|
|
|
|
2026.03.26 17:37:44.570 Test (EURUSD,H1) CRYPT_ARCH_ZIP = 7
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const uint8_t g_mqlarticles_entryptor_key_len[3] =
|
|
|
|
|
{
|
|
|
|
|
16, // CRYPT_AES128
|
|
|
|
|
32, // CRYPT_AES256
|
|
|
|
|
7 // CRYPT_DES
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const bool g_mqlarticles_entryptor_is_encrypther[8] =
|
|
|
|
|
{
|
|
|
|
|
false,
|
|
|
|
|
true,
|
|
|
|
|
true,
|
|
|
|
|
true,
|
|
|
|
|
false,
|
|
|
|
|
false,
|
|
|
|
|
false,
|
|
|
|
|
false
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
typedef uchar(*FuncGenerateRandomUchar)(void* ptr, uchar start, uchar stop);
|
|
|
|
|
uchar RandomSimpleGenerateRandomUchar(void* ptr, uchar start, uchar stop) { return (uchar)((CRandomSimple*)ptr).RandomShort(start, stop); }
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
class CEncryptor : public CLoggerBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
string m_key;
|
|
|
|
|
public:
|
|
|
|
|
CEncryptor(void) {}
|
|
|
|
|
~CEncryptor(void) {}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
void Key(const string& key) { m_key = key; }
|
|
|
|
|
__forceinline string Key() const { return m_key; }
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
bool SetAleatoryKey(ENUM_CRYPT_METHOD method, FuncGenerateRandomUchar f_generate_char, void* ptr = NULL, uchar chart_start = 32, uchar chart_stop = 255);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
bool EncryptFile(const string& file_name, bool common_flag, ENUM_CRYPT_METHOD method, bool delete_prev_file, string ext_encrypt = "");
|
|
|
|
|
bool DecryptFile(const string& file_name, bool common_flag, ENUM_CRYPT_METHOD method, bool delete_prev_file, string ext_decrypt = "");
|
2026-03-27 09:40:19 -05:00
|
|
|
bool DecryptFile(const string& file_name, bool common_flag, ENUM_CRYPT_METHOD method, bool delete_prev_file, uchar& res_data[]);
|
2026-03-31 07:24:07 -05:00
|
|
|
__forceinline bool DecryptFile(const string& file_name, bool common_flag, ENUM_CRYPT_METHOD method, bool delete_prev_file, string& res_data, int start,
|
|
|
|
|
int count = WHOLE_ARRAY, uint codepage = CP_ACP);
|
2026-03-26 18:15:47 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
bool EncryptText(const string& initial_text, ENUM_CRYPT_METHOD method, string& encrypted_text);
|
|
|
|
|
bool DecryptText(const string& encrypted_text, ENUM_CRYPT_METHOD method, string& decrypted_text);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CEncryptor::SetAleatoryKey(ENUM_CRYPT_METHOD method, FuncGenerateRandomUchar f_generate_char, void* ptr = NULL, uchar chart_start = 32, uchar chart_stop = 255)
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(!g_mqlarticles_entryptor_is_encrypther[method])
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("El metodo de encrypt = %s, no es de encryptacion de archivos", EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const uint8_t clen = g_mqlarticles_entryptor_key_len[method - 1];
|
|
|
|
|
m_key.Truncate(clen);
|
|
|
|
|
for(int i = 0; i < clen; i++)
|
|
|
|
|
{
|
|
|
|
|
m_key.SetChar(i, f_generate_char(ptr, chart_start, chart_stop));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CEncryptor::EncryptFile(const string& file_name, bool common_flag, ENUM_CRYPT_METHOD method, bool delete_prev_file, string ext_encrypt = "")
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(!g_mqlarticles_entryptor_is_encrypther[method])
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("El metodo de encrypt = %s, no es de encryptacion de archivos", EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const uint8_t clen = g_mqlarticles_entryptor_key_len[method - 1];
|
|
|
|
|
if(m_key.Length() != clen)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("La clave debe de tener un len de %u chars, con el metodo = %s", clen, EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
const int common_file_flag = (common_flag ? FILE_COMMON : 0);
|
|
|
|
|
int fh = FileOpen(file_name, FILE_BIN | FILE_READ | common_file_flag);
|
|
|
|
|
if(fh == INVALID_HANDLE)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al abrir el archivo = %s, ultimo error =%d", file_name, ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
uchar data[];
|
|
|
|
|
FileReadArray(fh, data);
|
|
|
|
|
FileClose(fh);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
uchar key_chars[];
|
|
|
|
|
StringToCharArray(m_key, key_chars, 0, clen);
|
|
|
|
|
|
|
|
|
|
//--- Encryptamos
|
|
|
|
|
uchar res[];
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
if(CryptEncode(method, data, key_chars, res) == 0)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al encriptar el archivo %s a AES256, ultimo error = %d", file_name, ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Creamos el archivo 2 (o sobreescribimos si ext = "")
|
2026-03-27 12:02:42 -05:00
|
|
|
// Para la extension como minimo se requiere dos caracteres el punto y algo eg: .h minimo de lo contraio se considera que no se desea extension
|
2026-03-26 18:15:47 -05:00
|
|
|
::ResetLastError();
|
2026-03-27 12:02:42 -05:00
|
|
|
fh = FileOpen((file_name + (ext_encrypt.Length() > 2 ? ext_encrypt : "")), FILE_BIN | FILE_WRITE | common_file_flag);
|
2026-03-26 18:15:47 -05:00
|
|
|
if(fh == INVALID_HANDLE)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al abrir el archivo = %s, ultimo error =%d", (file_name + ext_encrypt), ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
FileWriteArray(fh, res);
|
|
|
|
|
FileClose(fh);
|
|
|
|
|
|
|
|
|
|
//--- Ahora si eliminamso el archivo previo si es que se pide
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
if(delete_prev_file && !FileDelete(file_name, common_file_flag))
|
|
|
|
|
{
|
|
|
|
|
LogWarning(StringFormat("Fallo al eliminar el archivo = %s, ultimo error = %d", file_name, ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2026-03-27 12:02:42 -05:00
|
|
|
|
2026-03-26 18:15:47 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-27 09:40:19 -05:00
|
|
|
//| Desencripta un archivo |
|
|
|
|
|
//| file_name : ruta del archivo encriptado |
|
|
|
|
|
//| common_flag : true = carpeta Common, false = carpeta Files\ |
|
|
|
|
|
//| method : metodo de encriptacion usado al encriptar |
|
|
|
|
|
//| delete_prev_file: true = elimina el archivo encriptado original |
|
|
|
|
|
//| ext_decrypt : controla el nombre del archivo de salida: |
|
|
|
|
|
//| - "" = sobreescribe el mismo archivo |
|
|
|
|
|
//| - ".ext" = agrega extension file.enc → file.enc.ext |
|
|
|
|
|
//| - "-" = quita la ultima extension file.enc → file |
|
|
|
|
|
//| - ".ext-" = reemplaza ultima ext file.enc → file.ext |
|
2026-03-26 18:15:47 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CEncryptor::DecryptFile(const string& file_name, bool common_flag, ENUM_CRYPT_METHOD method, bool delete_prev_file, string ext_decrypt = "")
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(!g_mqlarticles_entryptor_is_encrypther[method])
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("El metodo = %s, no es de encryptacion de archivos", EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const uint8_t clen = g_mqlarticles_entryptor_key_len[method - 1];
|
|
|
|
|
if(m_key.Length() != clen)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("La clave debe de tener un len de %u chars, con el metodo = %s", clen, EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
const int common_file_flag = (common_flag ? FILE_COMMON : 0);
|
|
|
|
|
int fh = FileOpen(file_name, FILE_BIN | FILE_READ | common_file_flag);
|
|
|
|
|
if(fh == INVALID_HANDLE)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al abrir el archivo = %s, ultimo error = %d", file_name, ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
uchar data[];
|
|
|
|
|
FileReadArray(fh, data);
|
|
|
|
|
FileClose(fh);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
uchar key_chars[];
|
|
|
|
|
StringToCharArray(m_key, key_chars, 0, clen);
|
|
|
|
|
|
|
|
|
|
//--- Desencryptamos
|
|
|
|
|
uchar res[];
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
if(CryptDecode(method, data, key_chars, res) == 0)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al desencriptar el archivo %s, ultimo error = %d", file_name, ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Creamos el archivo destino (o sobreescribimos si ext = "")
|
2026-03-27 09:40:19 -05:00
|
|
|
// si ext_decrypt contiene el . entonces es exntesion si no el nombre del archivo out
|
|
|
|
|
string out_file_name = "";
|
|
|
|
|
if(StringFindCharWRef(ext_decrypt, '.'))
|
|
|
|
|
{
|
|
|
|
|
const uint len = (ext_decrypt.Length());
|
|
|
|
|
if(ext_decrypt[len - 1] == '-') // -. quiere decir elimina la extension previa y añade esta nueva
|
|
|
|
|
{
|
|
|
|
|
ext_decrypt.Truncate(len - 1); // quitamos el - final eg si tiewnmaos extdecurp como .txt- queda .txt
|
|
|
|
|
out_file_name = FileRemoveExtension(file_name) + ext_decrypt;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
out_file_name = file_name + ext_decrypt;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if(StringFindCharWRef(ext_decrypt, '-')) // quiere decir solo quita la extension que ya tenia
|
|
|
|
|
{
|
|
|
|
|
out_file_name = FileRemoveExtension(file_name); // Removes la primera extension (volvemos al extado original)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
out_file_name = file_name; // lo mismo sobrescribe
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Abrimos el archivo res
|
2026-03-26 18:15:47 -05:00
|
|
|
::ResetLastError();
|
2026-03-27 09:40:19 -05:00
|
|
|
fh = FileOpen(out_file_name, FILE_BIN | FILE_WRITE | common_file_flag);
|
2026-03-26 18:15:47 -05:00
|
|
|
if(fh == INVALID_HANDLE)
|
|
|
|
|
{
|
2026-03-27 09:40:19 -05:00
|
|
|
LogError(StringFormat("Fallo al abrir el archivo = %s, ultimo error = %d", out_file_name, ::GetLastError()), FUNCION_ACTUAL);
|
2026-03-26 18:15:47 -05:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
FileWriteArray(fh, res);
|
|
|
|
|
FileClose(fh);
|
|
|
|
|
|
|
|
|
|
//--- Ahora si eliminamos el archivo previo si es que se pide
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
if(delete_prev_file && !FileDelete(file_name, common_file_flag))
|
|
|
|
|
{
|
|
|
|
|
LogWarning(StringFormat("Fallo al eliminar el archivo = %s, ultimo error = %d", file_name, ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-27 09:40:19 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CEncryptor::DecryptFile(const string &file_name, bool common_flag, ENUM_CRYPT_METHOD method, bool delete_prev_file, uchar &res_data[])
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(!g_mqlarticles_entryptor_is_encrypther[method])
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("El metodo = %s, no es de encryptacion de archivos", EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const uint8_t clen = g_mqlarticles_entryptor_key_len[method - 1];
|
|
|
|
|
if(m_key.Length() != clen)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("La clave debe de tener un len de %u chars, con el metodo = %s", clen, EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
const int common_file_flag = (common_flag ? FILE_COMMON : 0);
|
|
|
|
|
int fh = FileOpen(file_name, FILE_BIN | FILE_READ | common_file_flag);
|
|
|
|
|
if(fh == INVALID_HANDLE)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al abrir el archivo = %s, ultimo error = %d", file_name, ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
uchar data[];
|
|
|
|
|
FileReadArray(fh, data);
|
|
|
|
|
FileClose(fh);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
uchar key_chars[];
|
|
|
|
|
StringToCharArray(m_key, key_chars, 0, clen);
|
|
|
|
|
|
|
|
|
|
//--- Desencryptamos
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
if(CryptDecode(method, data, key_chars, res_data) == 0) // Los datos lo ponemos en el array uchar proporcionado
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al desencriptar el archivo %s, ultimo error = %d", file_name, ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Ahora si eliminamos el archivo previo si es que se pide
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
if(delete_prev_file && !FileDelete(file_name, common_file_flag))
|
|
|
|
|
{
|
|
|
|
|
LogWarning(StringFormat("Fallo al eliminar el archivo = %s, ultimo error = %d", file_name, ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-28 21:46:51 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
__forceinline bool CEncryptor::DecryptFile(const string &file_name, bool common_flag, ENUM_CRYPT_METHOD method, bool delete_prev_file, string &res_data, int start, int count = WHOLE_ARRAY, uint codepage = CP_ACP)
|
|
|
|
|
{
|
|
|
|
|
uchar temp_data[];
|
|
|
|
|
if(!DecryptFile(file_name, common_flag, method, delete_prev_file, temp_data))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
res_data = CharArrayToString(temp_data, start, count, codepage);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 18:15:47 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CEncryptor::EncryptText(const string& initial_text, ENUM_CRYPT_METHOD method, string& encrypted_text)
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(!g_mqlarticles_entryptor_is_encrypther[method])
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("El metodo = %s no es de encryptacion", EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const uint8_t clen = g_mqlarticles_entryptor_key_len[method - 1];
|
|
|
|
|
if(m_key.Length() != clen)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("La clave debe de tener un len de %u chars, con el metodo = %s", clen, EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Convertimos el texto a uchar
|
|
|
|
|
uchar data[];
|
|
|
|
|
StringToCharArray(initial_text, data, 0, StringLen(initial_text));
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
uchar key_chars[];
|
|
|
|
|
StringToCharArray(m_key, key_chars, 0, clen);
|
|
|
|
|
|
|
|
|
|
//--- Encryptamos
|
|
|
|
|
uchar res[];
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
if(CryptEncode(method, data, key_chars, res) == 0)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al encriptar el texto, ultimo error = %d", ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Convertimos el resultado a BASE64 para poder guardarlo como string
|
|
|
|
|
uchar base64[];
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
if(CryptEncode(CRYPT_BASE64, res, key_chars, base64) == 0)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al convertir a BASE64, ultimo error = %d", ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
encrypted_text = CharArrayToString(base64);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CEncryptor::DecryptText(const string& encrypted_text, ENUM_CRYPT_METHOD method, string& decrypted_text)
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(!g_mqlarticles_entryptor_is_encrypther[method])
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("El metodo = %s no es de encryptacion", EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const uint8_t clen = g_mqlarticles_entryptor_key_len[method - 1];
|
|
|
|
|
if(m_key.Length() != clen)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("La clave debe de tener un len de %u chars, con el metodo = %s", clen, EnumToString(method)), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Convertimos el string BASE64 a uchar
|
|
|
|
|
uchar base64[];
|
|
|
|
|
StringToCharArray(encrypted_text, base64, 0, StringLen(encrypted_text));
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
uchar key_chars[];
|
|
|
|
|
StringToCharArray(m_key, key_chars, 0, clen);
|
|
|
|
|
|
|
|
|
|
//--- Decodificamos BASE64 primero
|
|
|
|
|
uchar data[];
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
if(CryptDecode(CRYPT_BASE64, base64, key_chars, data) == 0)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al decodificar BASE64, ultimo error = %d", ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Desencryptamos
|
|
|
|
|
uchar res[];
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
if(CryptDecode(method, data, key_chars, res) == 0)
|
|
|
|
|
{
|
|
|
|
|
LogError(StringFormat("Fallo al desencriptar el texto, ultimo error = %d", ::GetLastError()), FUNCION_ACTUAL);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
decrypted_text = CharArrayToString(res);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-03-27 09:40:19 -05:00
|
|
|
CEncryptor g_mqlarticles_encryptor;
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#endif // MQLARTICLES_UTILS_ENCRYPT_ENCRYPT_MQH
|