For keen DownVoters:
kindly notice first the given O/P context of use, where there are literally ZERO-options to chose any AES256-configuration options, but still the O/P needs to decipher the "black-box"-produced BLOBs on the php
-side. Thank you for re-consideration.
Feel free to improve the solution or present here in written any better solution for the O/P-given-use-case, which will be always warm welcome, won't it?
An MCVE
-segment of the practical solution below :
MQL4-side code :
//+------------------------------------------------------------------+
//| __StackOverflow_CryptENCODE.mq4 |
//| msMODs (1987-2016) |
//| nowhere.no |
//+------------------------------------------------------------------+
#property copyright "msMODs (1987-2016)"
#property link "nowhere.no"
#property version "1.00"
#property strict
#property script_show_inputs
extern string aKnown_OriginalSTRING_asMql4STRING = "How to decrypt an MT4 / AES256 encrypted string with PHP tools?";
uchar aKnown_OriginalSTRING_ucharCONTAINER[];
extern string aKnown_SecretKEY_asMql4STRING = "123456789o123456789o12";
uchar aKnown_SecretKEY_ucharCONTAINER[32];
uchar aCryptoBLOB_ucharCONTAINER[];
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart(){
StringToCharArray( aKnown_OriginalSTRING_asMql4STRING,
aKnown_OriginalSTRING_ucharCONTAINER,
0,
StringLen( aKnown_OriginalSTRING_asMql4STRING )
);
StringToCharArray( aKnown_SecretKEY_asMql4STRING,
aKnown_SecretKEY_ucharCONTAINER,
0,
32
);
int aFH = FileOpen( "DEMO_OUTPUT.txt", FILE_WRITE | FILE_TXT );
FileWrite( aFH, "START: GetLastError() == ", GetLastError(), "\n" );
FileFlush( aFH );
ResetLastError();
int nBYTEs = CryptEncode( CRYPT_AES256, // a principally unsure ENUM_ ( ref. above )
aKnown_OriginalSTRING_ucharCONTAINER,
aKnown_SecretKEY_ucharCONTAINER,
aCryptoBLOB_ucharCONTAINER
);
if ( nBYTEs > 0 ){
FileWrite( aFH, StringFormat( "OK.\nMQL4 CryptEncode() has produced [nBYTEs == %d ] bytes.\nMQL4 aCryptoBLOB_asHEX\n== [%s]",
nBYTEs,
show_asHEX( aCryptoBLOB_ucharCONTAINER )
)
);
Comment( "INF:",StringFormat( "OK.\nMQL4 CryptEncode() has produced [nBYTEs == %d ] bytes.\nMQL4 aCryptoBLOB_asHEX\n== [%s]\n\nSTORED IN GlobalVariable()...",
nBYTEs,
show_asHEX( aCryptoBLOB_ucharCONTAINER )
)
);
}
else
FileWrite( aFH, StringFormat( "ERR: in MQL4 CryptEncode()[ Err == %d ].",
GetLastError()
)
);
FileFlush( aFH );
FileClose( aFH );
}
//+------------------------------------------------------------------+
string show_asHEX( uchar &_ucharCONTAINER_arr[], int count = -1 ){
string HEX_asPrintableSTRING = "";
if ( count < 0
|| count > ArraySize( _ucharCONTAINER_arr )
) count = ArraySize( _ucharCONTAINER_arr );
for ( int ii = 0; ii < count; ii++ )
HEX_asPrintableSTRING += StringFormat( "%.2X", _ucharCONTAINER_arr[ii] );
return( HEX_asPrintableSTRING );
}
//+------------------------------------------------------------------+
Asks for user-input interaction:

And has produced ( on these default values ) a reference MCVE-output to validate any decipher-trial:
START: GetLastError() == 0
OK.
MQL4 CryptEncode() has produced [nBYTEs == 64 ] bytes.
MQL4 aCryptoBLOB_asHEX
== [1979FE46DB64652067C136F57F0971F20FB5C407CE043AAF972C8AED3DEB6D4260181448FE2FDF69AEA7DD8B33B1484A21935AAFBB649FB95DBB05BBA88E4A31]
Academia / Theoretical Approach :
Reverse scan all the possible configurations of the php
-tools of one's choice to find those settings, that correctly reconstruct the MT4-side CryptEncode()
-ed aKnown-[Test]-OriginalSTRING
, using aKnown-[Test]-SecretKEY
back to the matching string.
Being principally unsure about the MT4-side details ( where crypto-engine is due to obvious reasons not an open-source ), one faces the following possible alternatives for the (unknown-choice) on the encryption-process side:
CRYPT_BASE64
CRYPT_AES128
CRYPT_AES256
CRYPT_DES
CRYPT_HASH_SHA1
CRYPT_HASH_SHA256
CRYPT_HASH_MD5
The php
-decrypt-side is much "richer" to set an test
~ { OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING }
x { each-method-from-the-choice-below }
:
(
[0] => AES-128-CBC
[1] => AES-128-CFB
[2] => AES-128-CFB1
[3] => AES-128-CFB8
[4] => AES-128-ECB
[5] => AES-128-OFB
[6] => AES-192-CBC
[7] => AES-192-CFB
[8] => AES-192-CFB1
[9] => AES-192-CFB8
[10] => AES-192-ECB
[11] => AES-192-OFB
[12] => AES-256-CBC
[13] => AES-256-CFB
[14] => AES-256-CFB1
[15] => AES-256-CFB8
[16] => AES-256-ECB
[17] => AES-256-OFB
[18] => BF-CBC
[19] => BF-CFB
[20] => BF-ECB
[21] => BF-OFB
[22] => CAST5-CBC
[23] => CAST5-CFB
[24] => CAST5-ECB
[25] => CAST5-OFB
[26] => DES-CBC
[27] => DES-CFB
[28] => DES-CFB1
[29] => DES-CFB8
[30] => DES-ECB
[31] => DES-EDE
[32] => DES-EDE-CBC
[33] => DES-EDE-CFB
[34] => DES-EDE-OFB
[35] => DES-EDE3
[36] => DES-EDE3-CBC
[37] => DES-EDE3-CFB
[38] => DES-EDE3-OFB
[39] => DES-OFB
[40] => DESX-CBC
[41] => IDEA-CBC
[42] => IDEA-CFB
[43] => IDEA-ECB
[44] => IDEA-OFB
[45] => RC2-40-CBC
[46] => RC2-64-CBC
[47] => RC2-CBC
[48] => RC2-CFB
[49] => RC2-ECB
[50] => RC2-OFB
[51] => RC4
[52] => RC4-40
[53] => aes-128-cbc
[54] => aes-128-cfb
[55] => aes-128-cfb1
[56] => aes-128-cfb8
[57] => aes-128-ecb
[58] => aes-128-ofb
[59] => aes-192-cbc
[60] => aes-192-cfb
[61] => aes-192-cfb1
[62] => aes-192-cfb8
[63] => aes-192-ecb
[64] => aes-192-ofb
[65] => aes-256-cbc
[66] => aes-256-cfb
[67] => aes-256-cfb1
[68] => aes-256-cfb8
[69] => aes-256-ecb
[70] => aes-256-ofb
[71] => bf-cbc
[72] => bf-cfb
[73] => bf-ecb
[74] => bf-ofb
[75] => cast5-cbc
[76] => cast5-cfb
[77] => cast5-ecb
[78] => cast5-ofb
[79] => des-cbc
[80] => des-cfb
[81] => des-cfb1
[82] => des-cfb8
[83] => des-ecb
[84] => des-ede
[85] => des-ede-cbc
[86] => des-ede-cfb
[87] => des-ede-ofb
[88] => des-ede3
[89] => des-ede3-cbc
[90] => des-ede3-cfb
[91] => des-ede3-ofb
[92] => des-ofb
[93] => desx-cbc
[94] => idea-cbc
[95] => idea-cfb
[96] => idea-ecb
[97] => idea-ofb
[98] => rc2-40-cbc
[99] => rc2-64-cbc
[100] => rc2-cbc
[101] => rc2-cfb
[102] => rc2-ecb
[103] => rc2-ofb
[104] => rc4
[105] => rc4-40
)
Yes, it may take a long time, but this approach is principally possible.
Anyone interested in doing this may realise and ought verify also any kind of risk of becoming a subject of legal investigation or even legal enforcement task-force countermeasures, as under some local jurisdictions, using this or similar practice may be considered illegal and/or violating IP rights of some other party. ( So, 've just been warned. )
Practical Approach:
Go distributed.
Use php
-side to connect and communicate with MetaTrader Terminal 4 ( many ways to do so, incl. production-grade, low-latency frameworks ).
php
-side sends anMt4EncryptedBLOB
to the hands of an MT4-process
MT4-process calls the matching ( by design, the MetaQuotes' "home-made" - is a matching implementation of the encrypt/decrypt-service pair )
nBytes = CryptDecode( TheSAME_ENUM_CRYPT_METHOD, BLOBarray, KEYarray, RESarray );
Sending the RESarray
back to the php
-side for any further processing is obvious and useless to note here, but that closes the ring.
And you are done!
( Just do not get confused, that MQL4 string
is not in reality a string
but a struct
and similar suprises, that one will meet on the MT4-side, if going into DLL/API integration details, so be cautious. Still a pretty fun to hack this fast and smart into a rapid-prototyped MVP. )
An MCVE
-segment:
MQL4-side code:
//+------------------------------------------------------------------+
//| __StackOverflow_CryptENCODE.mq4 |
//| msMODs (1987-2016) |
//| nowhere.no |
//+------------------------------------------------------------------+
#property copyright "msMODs (1987-2016)"
#property link "nowhere.no"
#property version "1.00"
#property strict
#property script_show_inputs
extern string aKnown_OriginalSTRING_asMql4STRING = "How to decrypt an MT4 / AES256 encrypted string with PHP tools?";
uchar aKnown_OriginalSTRING_ucharCONTAINER[];
extern string aKnown_SecretKEY_asMql4STRING = "123456789o123456789o12";
uchar aKnown_SecretKEY_ucharCONTAINER[32];
uchar aCryptoBLOB_ucharCONTAINER[];
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart(){
StringToCharArray( aKnown_OriginalSTRING_asMql4STRING,
aKnown_OriginalSTRING_ucharCONTAINER,
0,
StringLen( aKnown_OriginalSTRING_asMql4STRING )
);
StringToCharArray( aKnown_SecretKEY_asMql4STRING,
aKnown_SecretKEY_ucharCONTAINER,
0,
32
);
int aFH = FileOpen( "DEMO_OUTPUT.txt", FILE_WRITE | FILE_TXT );
FileWrite( aFH, "START: GetLastError() == ", GetLastError(), "\n" );
FileFlush( aFH );
ResetLastError();
int nBYTEs = CryptEncode( CRYPT_AES256, // a principally unsure ENUM_ ( ref. above )
aKnown_OriginalSTRING_ucharCONTAINER,
aKnown_SecretKEY_ucharCONTAINER,
aCryptoBLOB_ucharCONTAINER
);
if ( nBYTEs > 0 ){
FileWrite( aFH, StringFormat( "OK.\nMQL4 CryptEncode() has produced [nBYTEs == %d ] bytes.\nMQL4 aCryptoBLOB_asHEX\n== [%s]",
nBYTEs,
show_asHEX( aCryptoBLOB_ucharCONTAINER )
)
);
Comment( "INF:",StringFormat( "OK.\nMQL4 CryptEncode() has produced [nBYTEs == %d ] bytes.\nMQL4 aCryptoBLOB_asHEX\n== [%s]\n\nSTORED IN GlobalVariable()...",
nBYTEs,
show_asHEX( aCryptoBLOB_ucharCONTAINER )
)
);
}
else
FileWrite( aFH, StringFormat( "ERR: in MQL4 CryptEncode()[ Err == %d ].",
GetLastError()
)
);
FileFlush( aFH );
FileClose( aFH );
}
//+------------------------------------------------------------------+
string show_asHEX( uchar &_ucharCONTAINER_arr[], int count = -1 ){
string HEX_asPrintableSTRING = "";
if ( count < 0
|| count > ArraySize( _ucharCONTAINER_arr )
) count = ArraySize( _ucharCONTAINER_arr );
for ( int ii = 0; ii < count; ii++ )
HEX_asPrintableSTRING += StringFormat( "%.2X", _ucharCONTAINER_arr[ii] );
return( HEX_asPrintableSTRING );
}
//+------------------------------------------------------------------+
Asks for user-input interaction:

And has produced ( on these default values ) a reference MCVE-output to validate any decipher-trial:
START: GetLastError() == 0
OK.
MQL4 CryptEncode() has produced [nBYTEs == 64 ] bytes.
MQL4 aCryptoBLOB_asHEX
== [1979FE46DB64652067C136F57F0971F20FB5C407CE043AAF972C8AED3DEB6D4260181448FE2FDF69AEA7DD8B33B1484A21935AAFBB649FB95DBB05BBA88E4A31]