2013-11-16 2 views
7

Я пытаюсь отправить зашифрованные данные по URL-адресу на другой сайт (используя file_get_contents("anotherUrl.php?hash=$encryptedString"). Проблема в том, что иногда шифрование содержит некоторые специальные символы, такие как +, и это приводит к расшифровке терпеть неудачуPHP, отправляющий зашифрованные данные по URL-адресу

Вот мои методы шифрования/дешифрования:.

public function encrypt($string, $key) 
{ 
    return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key)))); 
} 

public function decrypt($encrypted, $key) 
{ 
    return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encrypted), MCRYPT_MODE_CBC, md5(md5($key))), "\0"); 
} 

Вот пример зашифрованная строка, которая содержит +, и я предполагаю, что это приводит к тому, дешифрование сбой

. oWCrVPaS+5GbxcQFc0fulUk/zRAkDD60av4zlPiWskE=

Любые идеи, как я должен решить это? Я попытался сделать urlencode() и urldecode() на хэше, однако это также заставляет шифрование ломаться. Есть ли способ изменить алгоритм шифрования, чтобы заставить его возвращать только безопасные символы?

+0

Вопрос, почему вы выполняете две последовательные операции md5 на ключе? Чего вы хотите добиться от этого? – initramfs

+0

@CPUTerminator Фактически я скопировал функцию точно так же, как и из другого ответа здесь, на SO, я не внес никаких изменений в нее. –

+0

Эх ... Я не вижу в этом никакого смысла. Если ключ слабый (т. Е. Не из криптографически сильного генератора случайных чисел), вы не должны ** использовать 'md5' в качестве алгоритма усиления ключей (см.' PBKDF # 2', 'bcrypt' или' scrypt') , Если ваш ключ уже силен, вы просто теряете процессорные циклы. – initramfs

ответ

16

Посмотрите на эту тему:

Passing base64 encoded strings in URL

По сути вы DO хотите urlencode() перед отправкой строки, однако вы НЕ хотят urldecode() на другом конце.

+0

Спасибо, ты прав. Он работает с односторонним кодированием URL. (Не должно быть никакой функции декодирования url, если она не должна быть расшифрована, но для вас это PHP). –

+0

Существует много других случаев, когда требуется urldecode(), но это не один из них. Рад помочь. – jszobody

+1

«urlencode» необходимо, так как вы строите * строку запроса * здесь. С другой стороны PHP берет эту строку запроса и 'urldecode', что для вас, записывая результат в '$ _GET'. Это и есть причина асимметрии. Если бы вы сами разбирали строку * query *, вам также пришлось бы делать «urldecode» самостоятельно. –

5

Чтобы решить эту проблему, я теперь использую следующие (после 3 часов боли), и он отлично работает.

Вы можете копировать и вставлять

function encrypt($pure_string) { 
    $dirty = array("+", "/", "="); 
    $clean = array("_PLUS_", "_SLASH_", "_EQUALS_"); 
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB); 
    $_SESSION['iv'] = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
    $encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $_SESSION['encryption-key'], utf8_encode($pure_string), MCRYPT_MODE_ECB, $_SESSION['iv']); 
    $encrypted_string = base64_encode($encrypted_string); 
    return str_replace($dirty, $clean, $encrypted_string); 
} 

function decrypt($encrypted_string) { 
    $dirty = array("+", "/", "="); 
    $clean = array("_PLUS_", "_SLASH_", "_EQUALS_"); 

    $string = base64_decode(str_replace($clean, $dirty, $encrypted_string)); 

    $decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH, $_SESSION['encryption-key'],$string, MCRYPT_MODE_ECB, $_SESSION['iv']); 
    return $decrypted_string; 
} 
+0

Большое спасибо, идея str_replace была великолепна! – Sunit

2

Вместо того, чтобы использовать Base64 для кодирования ваших данных вы можете также использовать Base32 (RFC 4648), который является URL-безопасным, поскольку он использует только буквы A-Z (регистру нечувствительный) и цифры 2-7. Для кодирования/декодирования уже существует PHP library. Обратите внимание, что Base32 занимает ~ 20% больше места, чем Base64.

Вы также можете использовать URLcrypt, который представляет собой удобную библиотеку, которая поможет вам с шифрованием и кодировкой Base32.

Смежные вопросы