2017-01-19 2 views
1

У меня есть следующий код JavaScript, чтобы зашифровать строку с помощью ключа:PHP и JS Mcrypt дешифрования не работает

des.js это: 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> 

Затем я отправить его на стороне сервера и попытка расшифровать этот PHP код:

$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 пытался преобразовать его в utf8, изменение кодировки, изменение шестигранного декодирования и т.д., но она всегда выходит бред, иногда nonreadable чары в других случаях, как читаемый, но вздор.

+0

Лучше не использовать 'mcrypt', он оставался без изменений уже почти десять лет. Поэтому он устарел и будет удален из ядра и в PECL в PHP 7.2. Он не поддерживает стандартное дополнение PKCS # 7 (née PKCS # 5), только нестандартное нулевое заполнение, которое нельзя даже использовать с двоичными данными. 'mcrypt' имеет много выдающихся [ошибок] (https://sourceforge.net/p/mcrypt/bugs/), относящихся к 2003 году. Вместо этого используйте [defuse] (https://github.com/defuse/php-encryption) или [RNCryptor] (https://github.com/RNCryptor), они обеспечивают полное решение, поддерживаются и верны. – zaph

+0

Не используйте DES, он не защищен и был превзойден AES. Не используйте режим ECB, он небезопасен, см. [Режим ECB] (https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29), прокрутите вниз до пингвина. Вместо этого используйте режим CBC со случайным IV, просто префикс зашифрованных данных с помощью IV для использования в расшифровке, он не обязательно должен быть секретным. – zaph

+0

Вам нужно удалить «0x» из шестнадцатеричной кодированной строки (на самом деле, я бы попытался полностью переключиться с hex на base64). – LSerni

ответ

1

Путь расшифровать строку не работает должным образом, попробуйте это:

$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); 

Выход будет: привет мир

Таким образом, будет работать должным образом, однако, вы должны искать другой метод для шифрования ваших данных в вашем скрипте ключ (12345678) и ваш метод шифрования видны всем.

+0

Спасибо, я в конечном итоге использовал шифрование с открытым/закрытым ключом. Мой план состоял в том, чтобы использовать временный набор ключей в сеансе PHP, который был изменен ежечасно. – CarlosAllende

0

Данные, которые должны быть зашифрованы блочным шифрованием, таким как DES или AES, должны быть точным кратным размеру блока по длине. Решение заключается в добавлении дополнений к зашифрованным данным, заполнение PKCS # 5 является обычным дополнением для DES и, вероятно, значением по умолчанию для Javascript. К сожалению, mcrypt не поддерживает заполнение PKCS # 5, только нестандартное нулевое дополнение.

Возможные решения:

  1. Используйте лучшую функцию шифрования, чем Mcrypt см комментарий к вопросу.
  2. Не указывайте прописку в Javascript и вручную добавьте нулевое дополнение.
  3. Не указывать прописку в mcrypt и удалять заполнение вручную.

Лучше всего указать все параметры и не полагаться на значения по умолчанию.