1

I am trying to send over an encrypted URL and then decode it at the other end. Now the call I make is passed over but my decryption returns null.

Here's some of my code.

$this->_app_url . '?key=' . $this->_api_key . '&request=' .base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->_api_key, json_encode($url), MCRYPT_MODE_ECB));

The url is just a standard url, the key is a 32bit string so you can imagine it as anything. The $url variable is an array of stuff to be sent over. So that when I decrypt I have that array outright.

So at the other end I am trying to decode:

$key = $_REQUEST["key"];
$encrypted = $_REQUEST["request"];

$decrypted = json_decode(rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($encrypted), MCRYPT_MODE_ECB)));

This simply returns NULL, I can echo out the key and request and I get what i'm expecting but I just can't decrypt it.

mdixon18
  • 1,199
  • 4
  • 14
  • 35
  • Did you check `json_last_error`? – mim. Jul 14 '15 at 23:37
  • can you try `utf8_encode` before `json_decode` ? – mim. Jul 14 '15 at 23:43
  • still gives the same error if i put it before the decode. – mdixon18 Jul 14 '15 at 23:46
  • Please don't use `MCRYPT_RIJNDAEL_256` in ECB mode. Also, why are you transmitting the key? – Scott Arciszewski Jul 14 '15 at 23:51
  • What do you suggest i use? - transmitting the key for test purpose, later it will test keys from database. – mdixon18 Jul 14 '15 at 23:53
  • Oh, I have an = in my base64_encode() so i added urlencode before and then urldecode() before the decryption of the base64 to fix it. – mdixon18 Jul 15 '15 at 00:09
  • In order of decreasing preference: [libsodium](https://github.com/jedisct1/libsodium-php) (`crypto_secretbox()`) if you can, or one of these: [`defuse/php-encryption`](https://github.com/defuse/php-encryption) or [`\Zend\Crypt`](https://github.com/zendframework/zend-crypt). – Scott Arciszewski Jul 15 '15 at 00:28
  • 1
    @ScottArciszewski You forgot the most important one: SSL. Why encrypt just part of the data when you can encrypt the whole interaction? –  Jul 15 '15 at 03:48
  • Right, I was hoping `$this->_app_url` included `https://` at the beginning. – Scott Arciszewski Jul 15 '15 at 03:54

1 Answers1

0

This question has been asked a lot, with different word choice (which makes it difficult to say, "Just search for it!"). This fact prompted a blog post titled, The Comprehensive Guide to URL Parameter Encryption in PHP .

What People Want To Do Here

Some encryption function is used to deterministically retrieve the ID

What People Should Do Instead

Use a separate column

Explanation

Typically, people want short random-looking URLs. This doesn't allow you much room to encrypt then authenticate the database record ID you wish to obfuscate. Doing so would require a minimum URL length of 32 bytes (for HMAC-SHA256), which is 44 characters when encoded in base64.

A simpler strategy is to generate a random string (see random_compat for a PHP5 implementation of random_bytes() and random_int() for generating these strings) and reference that column instead.

If you must encrypt data (very much NOT recommended), don't use a homegrown design (and don't use mcrypt either!). Use a trustworthy library instead.

Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206