1

我有一个字符串,说“ My secret text”。

它已使用MQL4CryptEncode()函数(使用的方法所在的位置CRYPT_AES256)加密。

密钥(32 个字节)例如是“ 1234567890ABCDEFGHIJKLMNOPQRSTUV”。

MQL4 函数不提供输入IV可能性,也不知道是否使用CBC了-mode 或其他。

如何使用 PHP 取回“我的秘密文本”?

(我必须告诉,尝试过,但没有成功。)
openssl_decrypt(...)

mcrypt_decrypt(...)


更新:我从 MQ 得到答案:
使用的模式是ECB. 确实没用
。 所以,我的代码是:IV

<?php

$hexMessage       = $_POST["enc_data"];   //this is in hex form, I used ArrayToHex before sending
$encryptedMessage = hex2bin($hexMessage);
$encryptionMethod = "AES-256-ECB";  
$secretKey        = "1234567890ABCDEFGHIJKLMNOPQRSTUV";

$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretKey);

echo "Decrypted: $decryptedMessage";

?>

没有结果(即使我用作OPENSSL_RAW_DATA选项)。


Update2:
使用mcrypt_decrypt(...)它有效。但是,我很好奇为什么 openssl_decrypt(...) 没有工作(结果没有给出任何结果)?

4

2 回答 2

1

对于敏锐的 DownVoters:
请首先注意给定的 O/P 使用上下文,其中实际上有零选项可以选择任何 AES256 配置选项,但 O/P 仍然需要在"black-box"-side 上破译 - 产生的 BLOB php。感谢您重新考虑。

随意改进解决方案或此处以书面形式为 O/P-given-use-case 提供任何更好的解决方案,这将始终受到热烈欢迎,不是吗?


MCVE下面是实际解决方案的一个部分:
MQL4 端代码:

//+------------------------------------------------------------------+
//|                                  __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 );
   }
//+------------------------------------------------------------------+

要求用户输入交互: 在此处输入图像描述

并生成(在这些默认值上)参考 MCVE -输出以验证任何解密试验:

START: GetLastError() == 0
OK.
MQL4 CryptEncode() has produced [nBYTEs == 64 ] bytes.
MQL4 aCryptoBLOB_asHEX
== [1979FE46DB64652067C136F57F0971F20FB5C407CE043AAF972C8AED3DEB6D4260181448FE2FDF69AEA7DD8B33B1484A21935AAFBB649FB95DBB05BBA88E4A31]

学术界/理论方法:

反向扫描php一个人选择的 -tools 的所有可能配置,以找到那些正确重建 MT4 端CryptEncode()-ed 的设置aKnown-[Test]-OriginalSTRING,使用aKnown-[Test]-SecretKEY回匹配字符串。

由于主要不确定 MT4 方面的细节(其中加密引擎是由于明显的原因而不是开源的),因此在加密过程方面(未知选择)面临以下可能的替代方案:

CRYPT_BASE64
CRYPT_AES128
CRYPT_AES256
CRYPT_DES
CRYPT_HASH_SHA1
CRYPT_HASH_SHA256
CRYPT_HASH_MD5

-decrypt php-side设置测试更“丰富”
~ { 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
)

是的,这可能需要很长时间,但这种方法基本上是可行的。

任何有兴趣这样做的人都可能意识到并应该验证成为法律调查对象或什至执法工作组反措施的任何风险,因为在某些地方司法管辖区,使用这种或类似做法可能被视为非法和/或违反其他方的知识产权。(所以,刚刚被警告过。)


实用方法:

去分布式。

使用php-side 与 MetaTrader 终端 4 连接和通信(有很多方法,包括生产级、低延迟框架)。

php-side 发送anMt4EncryptedBLOB到 MT4 进程的手中

MT4 进程调用匹配(根据设计,MetaQuotes 的“自制” - 是加密/解密服务对的匹配实现)
nBytes = CryptDecode( TheSAME_ENUM_CRYPT_METHOD, BLOBarray, KEYarray, RESarray );

RESarray将背面发送到php-side 以进行任何进一步的处理是显而易见的,在这里需要注意的是无用的,但这会关闭环。

你完成了!
(只是不要混淆,MQL4string实际上不是一个,string而是一个struct类似的惊喜,如果进入 DLL/API 集成细节,人们将在 MT4 方面遇到,所以要小心。破解这个仍然很有趣快速和聪明地变成一个快速原型化的 MVP。)


An MCVE-segment:
MQL4 端代码:

//+------------------------------------------------------------------+
//|                                  __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 );
   }
//+------------------------------------------------------------------+

要求用户输入交互: 在此处输入图像描述

并生成(在这些默认值上)参考 MCVE -输出以验证任何解密试验:

START: GetLastError() == 0
OK.
MQL4 CryptEncode() has produced [nBYTEs == 64 ] bytes.
MQL4 aCryptoBLOB_asHEX
== [1979FE46DB64652067C136F57F0971F20FB5C407CE043AAF972C8AED3DEB6D4260181448FE2FDF69AEA7DD8B33B1484A21935AAFBB649FB95DBB05BBA88E4A31]
于 2016-12-12T09:23:55.170 回答
0

以下是两种不同的解密方式:

$decryptedMessage = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $secretKey, $encryptedMessage, MCRYPT_MODE_ECB);
$decryptedMessage = openssl_decrypt($encryptedMessage, "AES-256-ECB", $secretKey, OPENSSL_ZERO_PADDING|OPENSSL_RAW_DATA);
于 2017-03-08T14:46:26.813 回答