CarlosAllende
CarlosAllende

Reputation: 292

PHP & JS mcrypt decryption not working

I have the following code in Javascript to encrypt a string using a key:

des.js is this: http://www.tero.co.uk/des/code.php

<script src="/js/des.js"></script>
<script>
var key = '12345678';
var message = 'hello world';

var ciph = des(key, message, 1, 0);
ciph = stringToHex(ciph);
console.log("Encrypted Result: " + ciph);
</script> 

Then I send it server side and attempt to decrypt with this PHP code:

$key = '12345678';
$hexa = '0x28dba02eb5f6dd476042daebfa59687a'; /This is the output from Javascript
$string = '';
for ($i=0; $i < strlen($hexa)-1; $i+=2) {
$string .= chr(hexdec($hexa[$i].$hexa[$i+1])); }
echo mcrypt_decrypt(MCRYPT_DES, $key, $string, MCRYPT_MODE_ECB);

Ive tried converting it to utf8, changing encoding, changing the hex decoding, etc, but it always comes out gibberish, sometimes as nonreadable characters, other times as readable but nonsense.

Upvotes: 1

Views: 294

Answers (2)

rescobar
rescobar

Reputation: 1305

The way to decrypt the string is not working properly, try this:

$key = '12345678';
$hexa = '0x28dba02eb5f6dd476042daebfa59687a'; 

function hexToString ($h) {
  $r = "";
 for ($i= (substr($h, 0, 2)=="0x")?2:0; $i<strlen($h); $i+=2) {$r .= chr (base_convert (substr ($h, $i, 2), 16, 10));}
return $r;
}

echo mcrypt_decrypt(MCRYPT_DES, $key,hexToString('0x28dba02eb5f6dd476042daebfa59687a'), MCRYPT_MODE_ECB);

The output will be: hello world

This way work properly, however, you should search another method to encrypt your data, in your script the key (12345678) and your encrypt method is visible to everyone.

Upvotes: 1

zaph
zaph

Reputation: 112855

Data to be encrypted with a block cipher such as DES or AES must be an exact multiple of the block size in length. The solution is to add padding to the data to be encrypted, PKCS#5 padding is the usual padding for DES and probably the default for Javascript. Unfortunately mcrypt does not support PKCS#5 padding, only a non-standard zero padding.

Potential solutions:

  1. Use a better encryption function than mcrypt, see the comment to the question.
  2. Specify no padding in Javascript and manually add zero padding.
  3. Specify no padding in mcrypt and remove the padding manually.

It is better tospecify all options and no to rely on defaults.

Upvotes: 0

Related Questions