Umer
Umer

Reputation: 203

Why is CryptEncode() in mql4 different from other languages?

I was trying to understand CryptEncode() in order to send and receive strings between mt4 indicator and PHP server.

But when a string is encrypted on mql4 side it's totally different then when it's encrypted on the PHP side. Same key and same encryption algorithm is used on both ends, but still the encryption is different on both sides.

And when I use an online tool to decrypt the PHP encrypted string it successfully decrypts the sting, whereas when I use the mql4 generated encrypted string it says final block is not properly padded.

Code:

   string text="this is the text to be encoded";
   string keystr="d41d8cd98f00b204e9800998ecf8427e";
   uchar src[],dst[],key[];
    
    StringToCharArray(text,src);
    StringToCharArray(keystr,key);
    
       int encd=CryptEncode(CRYPT_AES256,src,key,dst);
       encd=CryptEncode(CRYPT_BASE64,dst,key,src);
       if(encd>0)
        {
          PrintFormat("Encoded data: size=%d, string='%s'",ArraySize(src),CharArrayToString(src));
        }
      else
         Print("Error in CryptEncode. Error code=",GetLastError());

Why is it that mql4 generated encrypted string different from a string generated by any other language? How to avoid this issue? Is there any alternative encryption library available to avoid this issue?

Upvotes: 0

Views: 898

Answers (2)

Ahmed Kamal
Ahmed Kamal

Reputation: 1

// PUTTING ALL THINGS TOGETHER

<?php
    $plaintext = '123456';
    $key = 'MyKey';
    $encryptedMessage = EncryptMQL($plaintext, $key);
    echo ($encryptedMessage);
    echo nl2br("\n");
    $decryptedMessage = DecryptMQL($encryptedMessage, $key);
    echo ($decryptedMessage);

    //--------------------------------------------------
    function EncryptMQL($plaintext, $key){
        $data .= "\0";  // string of MQL is terminated by null character
        $key .= "\0";
        $hash = hash('sha256', $key, true);  // true (raw binary) | false (lowercase hexits)
        $result = openssl_encrypt(padZero($plaintext), "AES-256-ECB", $hash, OPENSSL_ZERO_PADDING);
        // note: result = AES (base64 encoded)
        return $result;
    }

    function DecryptMQL($encryptedtext, $key) {
        $key .= "\0";
        $hash = hash('sha256', $key, true);  // true (raw binary) | false (lowercase hexits)
        $decrypted = openssl_decrypt($encryptedtext, "AES-256-ECB", $hash, OPENSSL_ZERO_PADDING);
        return(unpadZero($decrypted));
    }

    //--------------------------------------------------
    function padZero($data, $blocksize = 16) {
        $pad = $blocksize - (strlen($data) % $blocksize);
        return $data.str_repeat("\0", $pad);
    }
    function unpadZero($data) {
        return rtrim($data, "\0");
    }
?>

Upvotes: 0

PaulB
PaulB

Reputation: 1403

It is not different, it is just that MQL4 only supports a very specific implementation of AES encryption and unless you use the correct settings in your other code you will not achieve compatibility between the two platforms.

Specifically you need to ensure the following are implemented:

  • Padding Mode: Zeros
  • Cipher Mode: ECB (so no IV)
  • KeySize: 256
  • BlockSize: 128

You can try the online AES encryption/decryption tool to verify your results available here: The online toolbox

Upvotes: 1

Related Questions