0

I'm using Security utility for encryption and decryption in CakePHP 3.2. When I call

Security::encrypt('string', 'key') //key length is 32 or more

method over a string, it returns the encrypted string with some invalid characters like following:

8e88c050ff20cb12984bf1af24b11fc7ada198082c67d6b3da7170572d5bcd54���p���lp���������21ķ�;ܝ�%N�

I want to use this string in url. But it's not working as expected as there are some invalid characters.

Now I want to avoid these characters. Is there any way to avoid these character ?

Md Mahfuzur Rahman
  • 2,319
  • 2
  • 18
  • 28
  • Encryption is byte based, not character based. Printable characters are a subset of all byte values. Not all byte values are representable as printable characters. Many values can not be represented at all in many character encodings. – zaph Jun 26 '16 at 15:09

1 Answers1

6

Security::encrypt() returns binary data, there's nothing invalid about what you see.

If you need a URL safe string, then you for example use Base64 encoding as basis. That would however also require to take care of the URL unsafe characters that can occur in Base64, namely +, / and =:

// encode
$base64String = base64_encode($encryptedBinaryData);
$urlSafeString = str_replace(['+', '/', '='], ['-', '_', '~'], $base64String);

// decode
$base64String = str_replace(['-', '_', '~'], ['+', '/', '='], $urlSafeString);
$encryptedBinaryData = base64_decode($base64String);

If you're OK with a little more data, you could use hexadecimal encoding, which is completely URL safe:

// encode
$urlSafeString = bin2hex($encryptedBinaryData);

// decode
$encryptedBinaryData = hex2bin($urlSafeString);

See also

ndm
  • 59,784
  • 9
  • 71
  • 110
  • Actually Base64 is not URL safe, it contains the '/', '+' and '=' characters which are reserved, it still needs to be URL encoded. It does provide an ASCII representation of byte arrays and is shorter than a hexadecimal representation that is URL safe. '/' has special meaning in the path component of a URL, '= and '+' has special meaning in the query component of a URL – zaph Jun 26 '16 at 15:06
  • @zaph That's why there is the link to the SO question ("_Passing base64 encoded strings in URL_") where that exact problem is mentioned/solved, and that's also why I said to use Base64 as _basis_. – ndm Jun 26 '16 at 15:11
  • I would say that Base64 isn't generally URL safe. The comment qualifies in what situations Base64 is not safe without having to go to another question. – zaph Jun 26 '16 at 15:27
  • @zaph Of course it's not. I didn't mean to judge cour comment, I just wanted to explain myself, as your comment implied that my answer would create the impression that Base64 would be URL safe out of the box (with the additional hint that shouldn't be the case anymore). Generally I don't really see the point in repeating what has already been discussed to great extent in other questions, that's why I've only supplied a link. – ndm Jun 26 '16 at 15:47
  • Look here re: URL-safe base64 variant: http://stackoverflow.com/questions/5641303/base64url-in-java – Jim Flood Jun 28 '16 at 05:12
  • Cakephp does some weird stuff with urldecoding by default. So Im just leaving this here in case anyone needs to know how to solve this and don't spend a whole afternoon like me trying to see why it won't decrypt correctly ... https://github.com/cakephp/cakephp/issues/4723#issuecomment-56911357 – Jelmer Jan 05 '21 at 14:37
  • @Jelmer Not sure if/how you're problem is related exactly, but I've updated my answer to include the URL safe base64, and hex encoding as an alternative. – ndm Jan 05 '21 at 16:39
  • @ndm well, I was sending a Security::encrypted string over a GET request. In order to make it ASCII characters, I used base64_encode. Whenever you use the Router::url method to create an url, it automatically `urlencode` that parameter. So the `/` becomes `%2F`. This is fine. But then cakephp decides to automatically urldecode the complete request by default, so that `%2F` becomes a `/` again. Thereafter cakephp does the routing, therefore causing that one param to split up in 2. Basically costing me an afternoon.. so it's just a ref to anyone who needs to find that solution ;-) – Jelmer Jan 07 '21 at 12:39