0

I want to send the "message" to php as json data. But The "message" has to be a String. If I "stringfy" my json data in Javascript and encrypt them with "CryptoJS.AES.encrypt", I cannot get the single contents in PHP because "json_decode" always returns NULL.

I have used "json_last_error" and it returned 3. When I encode it with "utf8_encode" and json_encode them, it returns 0.

"mcrypt_decrypt" is the PHP AES-decryptor.

I really don't know what to do. Please help me and thanks in advance!

//JAVASCRIPT
    var encrypted = CryptoJS.AES.encrypt(
        JSON.stringfy({'message':'message','messageA':'messageA','messageB':'messageB'}),
        key512Bits500Iterations, {iv:iv});

    var data_base64 = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
    var iv_base64 = encrypted.iv.toString(CryptoJS.enc.Base64);
    var key_base64 = encrypted.key.toString(CryptoJS.enc.Base64);

    $.ajax({
  url: 'http://localhost/workspace/messageAppl.php',
  type: 'POST',
  data: {
          'data_base64':data_base64,
          'iv_base64':iv_base64,
          'key_base64':key_base64 //key_base64 will be encrypted with RSA
  },
     success: function(data){
         alert(data);
        },
        error: function(){
          alert('Index-Error');
     } 
    });

//    PHP

    // I can get the jsonString but I can't get the single message like 'message', 'messageA' or 'messageB'
         ...
         
     //Decryption in PHP
         public function jsMessage($data_base64, $iv_base64, $key_base64){
   $data_enc = base64_decode($data_base64); // data_base64 from JS
   $iv        = base64_decode($iv_base64);   // iv_base64 from JS
   $key       = base64_decode($key_base64);  // key_base64 from JS
  
   $plaintext = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $key, $data_enc, MCRYPT_MODE_CBC, $iv ), "\t\0 " );
   return $plaintext;
  }

         
    $json_string = aes_decrypt($_POST['data_base64'], $_POST['iv_base64'], $_POST['key_base64']);


    // json_decode returns NULL but WHY?
    $array=json_decode($json_string);

    $message=$array->message
    $messageA=$array->messageA
    $messageB=$array->messageB
**Edit 1**
The error message I get is:
**"Control character error, possibly incorrectly encoded"**

but the Json which I get in php after the decryption is valid:
{"message":"blablabalbalbalaballab","messageA":"blablabalbalbalaballab" ,"messageB":"blablabalbalbalaballab"}

and to be sure I'have tested the json again and again here



**Edit 2 **



I cannot post it with these signs that's the reason I've made a photo.

  • Does json_decode work if you do not encrypt the string? – Carson Crane Apr 10 '15 at 23:30
  • Shouldn't `stringify` be `JSON.stringify`? – Barmar Apr 10 '15 at 23:31
  • 5
    I hope this isn't how your application is really designed. Sending the key in the same AJAX request as the encrypted data makes no sense. If someone gets the encrypted message, they also get the key, so they can decrypt it themselves. – Barmar Apr 10 '15 at 23:32
  • 2
    Obviously there is something wrong with your decryption code. Please [edit] your question to add a reproducible example of your problem. – Artjom B. Apr 10 '15 at 23:40
  • @Barmar The key will be encrypted with RSA and JSON.stringify is not the problem. Everything is works fine with normal strings. But I do not want to encrypt and decrypt every single String because it tooks too much time.

    at Artjom B. : I have added the decrypt method.

    Thanks for your answers!
    – Hungry2Learn Apr 11 '15 at 08:53
  • @CarsonCrane Yes, everything works fine with a normal jsonString. Just after encrypted that jsonString with cryptojs in js, it returns null in php. Thanks for your answer! – Hungry2Learn Apr 11 '15 at 09:46
  • Can you explain your rtrim line? Looks like you are trying to remove the wrong type of padding. Try with just null \0 – Phil Apr 12 '15 at 20:12
  • @Phil_1984_ I have tried with "\0", "\t", "\n", "\x0B", "\r"... always the same output. – Hungry2Learn Apr 12 '15 at 21:55

3 Answers3

1

the user notes on mcrypt_decrypt() has the answer

It appears that mcrypt_decrypt pads the RETURN STRING with nulls ('\0') to fill out to n * blocksize

$json = rtrim($json, "\0");
Jeremy French
  • 11,707
  • 6
  • 46
  • 71
0

It looks like you are base64 encoding the encrypted json string. However you are not base64 decoding it in your PHP example before you attempt to decrypt.

Also if your decrypt function is mcrypt_decrypt then you are passing the parameters wrong, it needs to be mcrypt_decrypt($cipher, $key, $data, $mode, $iv).

Edit: more info

It also appears that you are base64 encoding the other values you pass in your ajax call but don't decode them on php side in your example, will need to do thast as well.

Community
  • 1
  • 1
Nilithus
  • 121
  • 1
  • 3
  • The decryption works fine with a normal String. I have edited my question. Please take a look at my decryption code. I can get the jsonString but I cannot parse the jsonString in php – Hungry2Learn Apr 11 '15 at 08:58
-1

Explanation
Scenario: In JS I encrypt the jsonString with cryptojs. In PHP I decrypt it with "mcrypt_decrypt".
But the JsonString which I get in php after the decryption has some funny characters in the end.
I can only see these characters if I copy the output of var_dump() and paste it to the IDE (i.e. notepad++, eclipse, etc.).

These characters are always 12. I do not know where they come from (Maybe while the message is encrypted or decrypted), but after "substring" them, I can get a valid jsonString for "json_decode()".

solution
I just substring the 12 invisible characters after the last curly bracket and it works. I hope it helps someone.

json_decode(substr( $json, 0, strlen( $jsonString)-12));


EDIT

Better use this:
$strPad = ord($json[strlen($json)-1]);
$n_data = substr($json, 0, -$strPad); 
$row=json_decode($n_data );

than

json_decode(substr( $json, 0, strlen( $jsonString)-12));

So You don't need to count the points you have to delete like I did.